Swift2 メモ


WWDC 2015でSwift2が発表されました。
詳しいことはリファレンスみないと分かりませんが流れている情報をメモ。

公式WEBサイトでは早速Swift2について紹介されています。
https://developer.apple.com/swift/

公式リファレンス - The Swift Programming Language
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/index.html#//apple_ref/doc/uid/TP40014097-CH3-ID0

iBooks - The Swift Programming Language (Swift 2 Prerelease) ※ ~~日本では今現在読めません...~~ 読めます！
https://itunes.apple.com/us/book/swift-programming-language/id1002622538


- オープンソース化
- Linux対応 (2015 Fall)
- ビルド時間、コンパイル時間の短縮
- Markdownでコメントが書ける
- Error handling model(try catch)の追加
- ステートメントの追加(do / guard / defer / repeat) 
- Protocolが拡張可能に
- Optional Patternの追加
- ラベル指定breakがif文に対しても指定可能に


## Error handling model
標準のエラーハンドリング方法が追加されるようです。
Swift1.2までではコミュニティで(独自実装の)Eitherの使用が提案されていたりしましたが
こちらに落ち着くんでしょうか。

```swift
func loadData() throws { }

func test() {
	￼do {
		￼try loadData()
	} catch {
		￼print(error)
	}
}
```

#### 追記：独自エラーを定義する方法
こんな感じで独自に定義したエラーを投げて、個別にキャッチできるようです。

```swift
enum MyError : ErrorType {
    case InvalidData
    case OutOfLength
}

func PrintName(data: [String: String]) throws -> String {
    guard let name = data["name"] else {
        throw MyError.InvalidData
    }

    guard name.utf8.count > 0 else {
        throw MyError.OutOfLength
    }
    
    print(name)
    
    return name
}

do {
    var name = try PrintName(["name":"John"])
    print(name)
} catch MyError.InvalidData {
    print("Invalid Data")
} catch MyError.OutOfLength {
    print("OutOfLength")
}
```

サンプルでは試しにエラーを投げる関数が戻り値を返すようにしてみましたが、
tryしてる行の見た目がすごく気持ち悪いです・・・。


## Availability
APIが使用可能かチェックする方法が追加されるようです。

<blockquote class="twitter-tweet" lang="ja"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/Swift2?src=hash">#Swift2</a> has API availability checks <a href="http://t.co/4LVtC8CJhq">pic.twitter.com/4LVtC8CJhq</a></p>&mdash; Albert Hernández (@ahernandezlopez) <a href="https://twitter.com/ahernandezlopez/status/608001829071429632">2015, 6月 8</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


## Syntax improvements
新しいStatementが幾つか追加されるようです。

### do
catchを行いたいスコープを宣言するようです。
Error Handling modelのサンプル参照。

### guard
Early Exitと紹介されています。
関数が要求する条件を満たしているかをチェックする時に使うということのようです。
ifと似てる、というか同じとしか思えませんが可読性の向上のために用意されているようです。

```swift
func greet(person: [String: String]) {
    guard let name = person["name"] else {
        return
    }
    
    print("Hello \(name)!")
    
    guard let location = person["location"] else {
        print("I hope the weather is nice near you.")
        return
    }
    
    print("I hope the weather is nice in \(location).")      
}

greet(["name": "John"])
// prints "Hello John!"
// prints "I hope the weather is nice near you."

greet(["name": "Jane", "location": "Cupertino"])
// prints "Hello Jane!"
// prints "I hope the weather is nice in Cupertino."
```

関数の先頭でしか使えないのかな？と思いましたが
サンプルコードを見る限りどこでも良いみたいです。

~~return, break, continueおよび関数/メソッド呼出は可能だけど、
returnで関数/メソッド呼出は出来ないようです。（なんでだろ？）~~
試してみたらできました、読み違えていたようです・・・


#### 追記：ifとの違いについて
よく見るとguard letで宣言してる定数nameが後で使えているのでifとは違いました・・・。

```swift
guard let name = person["name"] else {
    return
}
print("Hello \(name)!")   // name が使えてる！
```

### defer
遅延実行ができるようです。

```swift
func f() {
    defer { print("First") }
    defer { print("Second") }
    defer { print("Third") }
}

f()
// prints "Third"
// prints "Second"
// prints "First"
```

ファイルディスクリプタを閉じる時とかリソース管理とかで使ってね、ということみたいです。

### repeat
他言語によくあるdo-whileループのSwift版、ということみたいです。

```swift
var i = 0
repeat {
    ++i
} while i < 10
```

## Optional Pattern
Optionalに関して新しい記述方法が追加されたようです。
パッと見では、どういう時に使うと嬉いか思いつきません・・・。

```swift
let someOptional: Int? = 42

if case .Some(let x) = someOptional {
    print(x)
}

if case let x? = someOptional {
    print(x)
}
```

for-in文にも新しい記述方法が追加されています。
nilでない要素を拾えるようです。こちらはわかりやすいですね。

```swift
let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]

for case let number? in arrayOfOptionalInts {
    print("Found a \(number)")
}
```


## ラベル指定breakがif文でも指定可能に
多重ループを抜ける場合に使うと便利なラベル指定が
Swift2ではif文に対しても使えるようになったようです。使い所が思いつきません。

```swift
MyLabel: if true {
    while true {
        break MyLabel
    }
    print("whill never be executed")
}
```
・・・これ必要なんでしょうか？