optionalについて簡潔にまとめてあるものが少なかったのでまとめてみた。
どういう場合に必要になるか
- 変数に
nil
を代入したい場合 - 引数に
nil
を受け取る場合
通常宣言された変数にはnil
を代入することはできないが、変数をoptional宣言(ラップ)することでnil
を代入することができるようになる。
使い方
型アノテーションの末尾に?
を付けて宣言する。初期値はnil
になる。
var optionalString: String?
optionalString = "Hello"
ただ、optional変数はnil
が含まれる可能性があるため、optionalでない変数として扱うことはできない。
func printString(string: String) {
println("\(string)")
}
var optionalString: String? = "Hello"
// ビルドエラー
printString(optionalString)
この場合は、!
を使用(アンラップ)してoptional変数がnil
ではないことを明示的にしなければならない。
printString(optionalString!)
ただ、!
を使用した際に変数の中身がnil
だと実行時に処理が落ちてしまうので都度確認する必要がある。
// 初期値はnil
var optionalString: String?
// 中身がnilなので実行時エラー
printString(optionalString!)
if optionalString != nil {
// !を付けてnilでないことを明示的に(アンラップ)する
printString(optionalString!)
}
あるいはif
を使ってoptional変数の中身を取り出すことができ、こちらのほうが便利で一般的。
var optionalString: String? = "Hello"
// nilではないことを証明
if let string = optionalString {
// stringはnilではないことが確約(アンラップ)されている
printString(string)
}
ちなみに以下の記述は落ちる。
// 初期値はnil
var optionalString: String!
// 実行時エラー
printString(optionalString)
ちなみに以下の記述は通る。
// 初期値はnil
var optionalString: String!
// nilは許容される
func printString(string: String!) {
println("\(string)")
}
// nilでも大丈夫
printString(optionalString)
まとめ
- 変数に
nil
が入る可能性が無いなら、宣言時に何も付けない - 変数に
nil
が入る可能性があるなら、宣言時に!
か?
をつける -
!
はoptional変数がnil
ではないと思われる際につける -
?
はoptional変数がnil
でも構わない時につける