The Swift Programming Language 勉強記録 - 2

前回に続き、Swiftの勉強記録その2。

function

Swiftの関数はこんな感じの記述。

func addExpression(x: Int, y: Int) -> Int {
    return x + y
}
addExpression(6, 12) // 18

可変長引数もできるし、複数の値返却も可能。

func sumOf(numbers: Int...) -> (sum: Int, avg: Double) {
    var sum = 0
    , counter = 0;
    
    for number in numbers {
        sum += number
        counter++
    }
    
    return (sum, Double(sum)/Double(counter))
}
let result = sumOf(1,2,3)
result.sum // 6
result.0   // 6(indexで参照する戻り値を指定することもできる)
result.avg // 2.0
result.1   // 2.0 
let result2 = sumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
result2.avg // 5.5

関数のネストもOK。

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

Swiftの関数はfirst-class、つまり第一級関数である。
関数を変数に代入することもできるし、関数の引数として渡すことも、戻り値として返すこともできる。

func makeSquareNumber() -> (Int -> Int) {
    func multiplication(number: Int) -> Int {
        return number*number
    }
    // 関数を返す
    return multiplication
}
makeSquareNumber()(5) // 25
// 戻り値の関数を変数squareに代入
var square = makeSquareNumber()
square(10) // 100
func hasAnyMatches(list: [Int], condition: (Int, Int) -> Bool) ->Bool {
    for item in list {
        if (condition(item, 12)) {
            return true
        }
    }
    return false
}
func addValueLessThanTwenty(number: Int, addValue: Int) -> Bool {
    return number+addValue < 20
}
var numbers = [20, 19, 7, 12]
// hasAnyMatches関数の引数にaddValueLessThanTwenty関数を渡す
hasAnyMatches(numbers, addValueLessThanTwenty) // true

closure

ドキュメントには"関数はクロージャの特殊なケースだ"とある。

Functions are actually a special case of closures

実はfuncによる関数定義の形は、クロージャを作成する際の記述形式の糖衣構文である。
例えば、先に挙げたaddExpression関数についてクロージャを作成する形で記述すると、次のようになる。

let addExpression: (Int, Int) -> Int = {
    (x: Int, y:Int) -> Int in
    return x + y
}
addExpression(30, 40) // 70

クロージャはブレース{}で囲まれた部分。
引数と戻り値の型を記述したあとinを挟んで実処理を記述していくことでクロージャを作成できる。
上記のコードは、クロージャをaddExpression変数に代入し、addExpression関数を呼び出したときのようにクロージャを呼び出すことを可能にしている。

なお、クロージャ型推論や$0, $1といったショートハンド引数、returnの省略などによって記述を簡略化できる。

let minusValues: (Int, Int) -> Int = { (x: Int, y: Int) -> Int in return x - y }
let minusValues: (Int, Int) -> Int = { x, y in x - y }
let minusValues: (Int, Int) -> Int = { $0 - $1 }

上記3つのコードはすべて同じ動作を意図している。

以上。次は多分クラスです。