A Swift Tourその2 – Functions and Closures

LINEで送る
Pocket

Swiftの言語仕様である「The Swift Programming Language」に沿って、学んでいきます。

The Swift Programming Language

Functions and Closures / 関数とクロージャ

関数を定義するには func を使います。
パラメータの型と戻り値の間を -> でつなげます。
CoffeeScriptみたいですね。

func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday") // "Hello Bob, today is Tuesday."

関数から複数の値を返したいとき等、複数のオブジェクトをまとめて扱いたいときにはタプルを使います。
タプルは要素名やインデックスで値が取り出せます。
タプルがあるのはPythonぽいです。
辞書や配列に似ています。

func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0
    
    for score in scores {
        if score > max {
            max = score
        } else if score < min {
            min = score
        }
        sum += score
    }
    
    return (min, max, sum)
}
let statistics = calculateStatistics([5, 3, 100, 3, 9]) // (min:3, max:100, sum:120)
statistics.sum  // 120
statistics.2    // 120

引数として配列を渡すことで、関数は複数の引数を取ることができます。

func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}
sumOf()            // 0
sumOf(42, 597, 12) // 651

関数は入れ子にすることができます。外側の関数で宣言された変数は内側の関数で参照することができます。

func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5    // 15
    }
    add()
    return y      // 15
}
returnFifteen()   // 15

関数はファーストクラスであり、つまり関数を型のように扱えます。
関数の戻り値に関数を指定できます。

func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne // 関数を返す
}
var increment = makeIncrementer()
increment(7)  // 8

関数の引数にも関数を指定できます。

func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool {
    for item in list {
        if condition(item) { // 第2引数のconditionは関数
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen) // true

関数はクロージャの一種です。
関数は名前をつけて定義しなくてもいい、無名関数というのがあります。
関数も無名関数も含めて、クロージャです。
無名関数はfuncで定義する代わりに中括弧({})で囲みます。
本体は中かっこで囲まずに、戻り値と本体の間に in をおきます。

numbers.map({                // [60, 57, 21, 36]
    (number: Int) -> Int in
    let result = 3 * number
    return result
})

クロージャは、引数や戻り値の型が分かっている場合は、型を書かなくてもいいです。

let mappedNumbers = numbers.map({ number in 3 * number })
mappedNumbers    // [60, 57, 21, 36]

引数は変数名でなく数字で参照することができます。
短いクロージャには便利です。

let sortedNumbers = sorted(numbers) { $0 > $1 }
sortedNumbers    //  [60, 57, 21, 36]

「A Swift Tourその3」に続きます。

「The Swift Programming Language」で使用されているコードはplaygroundとしてダウンロードして、XCodeで開くことができます。
https://developer.apple.com/library/ios/swift_tour

LINEで送る
Pocket

コメントを残す