Optional型の勘所

(書いている途中で[書きたかったことがだいたい書いてある記事](http://qiita.com/naodroid/items/75b70e18fa1edda6d91e)が公表されたので、方向性を変えています)

# 要旨
* 代入先がOptional型なら、optional chainingを代入できる
* `if let`もいいが`??`も便利
* `as?`を使えば色々と楽
* Implicitly Unwrapped Optional型をnilチェックしてはならない

# 内容
## 趣旨
　Swiftをいじり倒してみると、思った以上にオプショナル型が強力であって「書きたいことを書ける」と分かってきました。「オプショナル型のなにが便利なんだ？」「どう使えばいいんだ？」「`if let`書きまくりで面倒なだけなんだが？」という人の参考になるものを書いてみたいなと。
　ただし、以下の内容 (特に最後の部分) は私が勝手にそう考えているだけなので、あくまで参考程度にしたほうがよいかもしれません。

　なお純粋な仕様については[こちら](http://qiita.com/cotrpepe/items/518c4476ca957a42f5f1)が詳しいので、解説しません。

## 代入先がOptional型なら、optional chainingを代入できる
　仕様をちゃんと読むと書いてあるのですが、Optional型のチェーンは「もしそれがnilなら、その式はnilを返す」というものです。

```swift
// hogeはInt?型
var hoge: Int? = 10

// hoge?... はnilを返す(かもしれない)
// そこでfugaもInt?型になる
let fuga = hoge?.advancedBy(10)
```

　ということは、代入先をオプショナル型にしておけば、いちいちforced unwrappingしないまま次々に代入していけるわけです。

```swift
// いちいちforced unwrappingする場合
// もしnilだとエラーになる
var goho: Int
gogo = fuga!.advancedBy(10)

// 代入先もオプショナルなので、これで通る
var hoho: Int?
hoho = fuga?.advancedBy(10)
```
　nilチェックする必要がないとき、適切に先送りして処理を単純化できます。

## `if let`もいいが`??`も便利

　nilかもしれない値を取り出すとき、`if let/var hoge = ...  else ...`などと書くことができます。処理を分岐させるなら、素直にこれを使うことになりますが、ただオプショナル型を非オプショナル型に変換するだけなら`??`で十分ということもあります。

```swift
// fugaはnilかもしれないので、fuga?.advancedBy(10) はnilかもしれない
// そのときは0を返す
let result = (fuga?.advancedBy(10)) ?? 0
// resultはnilになり得ないので、Int型になる
```

　文脈によって便利なものを使えばOKですね。
## `as?`を使えば色々と楽
　`as?`は「キャストできればキャストし、無理ならnilを返す」というものです。
　色々と使い道がありますが、たとえば中身の予想されるNSArrayやNSDictionaryなどをSwiftらしく使えます。

```swift
import Cocoa

// 何らかの理由で、[String:[Int]] が戻り値と予想できる関数
func testFunc() -> NSDictionary {
    return ["test": [100,200,300], "text": [10]]
}

if let d = testFunc() as? [String:[Int]] {
    // d: [String:[Int]] であることは確定
    // したがって d[0] と書くことはできない
}
```

　JSONや.plistの処理あたりで使えるかもしれません。

## Implicitly Unwrapped Optional型をnilチェックしてはならない
　`Int!`型や`String!`型について、「nilかも知れないので、チェックしなければならない」とか、「中身がnilでも構文上エラーにならず、稼働時に落ちるので、なるべく使わないほうがよい」という人もいます。
　しかし考えてみると、これは全く逆であって、「**Implicitly Unwrapped Optional型は “nilであってはならない変数” に使うものであり、nilである場合のエラーを回避してはならない**」「**絶対に必要なものは`!`にするほうがよい**」というべきです。

　たとえばXcodeでは、`@IBOutlet ... UITextField!` などと入力されます。これは決して「nilかも知れないので毎回注意すべし」という意味ではありません。インスタンス変数なので**理屈上はnilかも知れないが、実際にnilだと困るので、絶対にnilではないと保証されている**と考えるべきです。
　そのような不可欠のインスタンス変数に`?`を付けてしまうと、ミスの温床になるでしょう。

```swift
// 何らかの理由で、viewDidLoadなどで設定すべき変数
var hogeManager: HogeManager?

override func viewDidLoad() {
    super.viewDidLoad()

    // hogeManager = HogeManager() を書き忘れても問題なく動いてしまう
    hogeManager?.requestHoge()
}
```

　`Int!`型や`String!`型についても、「理論上はnilかも知れないが、仮にnilのままであればミスである」という場合に使うべきです。仕様上nilかもしれない場合には`?`型を使うべきであり、**Implicitly Unwrapped Optional型を使う以上、nilチェックによりエラーを回避すべきではありません。**エラーを発生させてミスを探すべきです。


```swift
// 何らかの理由でイニシャライザのないクラス
class Hoge {
    // タイトルとナンバーが必須だが、その設定は人力で確保しなければならない
    var title: String!
    var number: Int!
    func hogeInt() -> Int {
        // title = nilだとエラーになる構文
        return (title.toInt() ?? 0) + number
        // しかしtitle: String!型なので警告されない

        // もしtitle: String?型なら、Xcodeの自動補正でtitle?.toInt()と入力される
        // その場合 title = nil でも式が正常に評価されてしまう
    }
}

let hoge = Hoge()

// titleとnumberはnilであってはならない
// 書き漏らすとエラーになるので発覚する
hoge.title = "5050"
hoge.number = 4649
hoge.hogeInt() // -> 9699
```

　素の型･`?`型･`!`型を使い分けることで、変数の性格を適切に表現することができます。