しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

Swift再入門8 − The Swift Programming Languageを読んでみる

この記事では「The Swift Programming Language」を1から読んだ感想とか発見を書いてみようと思います。
「The Swift Programming Language」とはSwiftの公式ドキュメントでiBooksや下ページで見る事ができます。

The Swift Programming Language: About Swift

読んだ所

今回はClosuresという項目を読みました。

The Swift Programming Language: Closures

学んだこと

Closureの省略法

配列のソートは下のようにクロージャーを引数として渡します。

let sorted = [3, 2, 1, 5, 4].sorted({ (value1: Int, value2: Int) -> Bool in
    return value1 < value2
})
NSLog("\(sorted)")

括弧と戻り値は型推論が効くので省略可能です。

let sorted = [3, 2, 1, 5, 4].sorted({ value1, value2 in
    return value1 < value2
})
NSLog("\(sorted)")

式の中身が1行の場合はreturnも省略できます。
2行以上の場合はreturn必須です。

let sorted = [3, 2, 1, 5, 4].sorted({ value1, value2 in
    value1 < value2
})
NSLog("\(sorted)")

第1引数、第2引数は省略して$0・$1と書くこともできます。

let sorted = [3, 2, 1, 5, 4].sorted({ $0 < $1 })
NSLog("\(sorted)")

省略ではないのですが、Closureは()の外側に出す事もできます。

let sorted = [3, 2, 1, 5, 4].sorted() { $0 < $1 }
NSLog("\(sorted)")

他に引数がない場合は()自体を省略できます。

let sorted = [3, 2, 1, 5, 4].sorted { $0 < $1 }
NSLog("\(sorted)")

実は更に省略してsorted(<)と書く事ができます。
<は関数なので引数として渡す事ができます。

let sorted = [3, 2, 1, 5, 4].sorted(<)
NSLog("\(sorted)")

// < の定義
// func <(lhs: Int, rhs: Int) -> Bool

演算子の定義

先ほど"<は関数"と書いたのですが、この関数は自分で定義する事もできます。

下のようにAの比較関数を作っておけば実際に比較演算子を使う事ができます。

class A {}
func <(a: A, b: A) -> Bool { return true }

A() < A()

autoclosure

利用頻度は低そうですが、Swiftにはautoclosureという機能があります。
これを使うと、引数を自動でクロージャーにしてくれます。

これを使う事で関数内の好きなタイミングで引数を実行する事ができます。

func method1(@autoclosure method: () -> Int) {
    print(method())
}
method1(1)

// 下がautoclosureを使わない場合
// method2({ 1 })と呼び出し側でクロージャーで囲む必要がある
func method2(method: () -> Int) {
    print(method())
}
method2({ 1 })

Swiftでは&&や??や||で使われていました。
1つ目の引数次第で2番目の引数を実行したくないので使っているようです。

func &&<T : BooleanType>(lhs: T, rhs: @autoclosure () -> Bool) -> Bool

func ??<T>(optional: T?, defaultValue: @autoclosure () -> T?) -> T?