配列の要素をオプショナルバインディング
はじめに
コードレビューで、ちょっと不思議なコードがあったのでメモ。
結論
配列の添字アクセスをオプショナルバインディングしてもビルドエラーにならないけど、わかりにくいのでやめたほうがいい。
コード
var hoge:[Int] = [] // hogeを更新する処理など if let n: Int = hoge[0] { //ランタイムエラー print(n) } else { print("nothing") }
一見すると良さそうですが、配列が空っぽなのでコメントした行で fatal error: Index out of range
になります。
当たり前といえば当たり前ですね。
改善案
配列でこういった判定を行うなら、空配列の判定したほうがわかりやすい気がします。
if hoge.isEmpty { print("nothing") } else { print(hoge[0]) }
そもそも、配列アクセスでnil
が返る可能性を想定したコードになっていますが、hoge
はInt
型の配列であって、Optional<Int>
型の配列ではないので、オプショナルバインディングは適切ではないです。
なんでビルドエラーにならないのかは謎です。
どうしてもオプショナルバインディングしたい場合
if let n: Int = hoge.first { print(n) } else { print("nothing") }
今回の場合は、配列の最初の要素にアクセスしたいので、Array
クラスの first
プロパティでOK。
first
はオプショナル型なので問題なし。
似たようなプロパティとして最後の要素を参照する last
もあります。
どちらも正確には Array
クラスに適用している CollectionType
プロトコルの特徴ですが。