Swiftの「Optional Value」の使い方
Optional Value
Swiftのコードを読んでいると変数の横に「?」や「!」がついていることがあります。
この「?」がついているものが「Optional Value」になります。
Optional Value の宣言
var optionalValue:String? = "オプショナルです"
型の横に「?」をつけるだけです。
これでnilも代入可能なString型のオブジェクト完成です。
var normalValue:String = "オプショナルじゃない" normalValue = nil //error var optionalValue:String? = "オプショナルです" optionalValue = nil //OK
実際は、Optional<Int>のような型宣言になりますが、「?」をつけるだけでOKです。
nilを許容していないオブジェクトに対してnilを代入しようと、「Could not find an overload for '__conversion' that accepts the supplied arguments」というエラーがでます。
Optional Value を代入するときの注意
Optionalじゃない変数にOptional Valueを代入しようとすると、エラーになります。
let number = "123" let convertedNumber = number.toInt() var intNumber:Int = convertedNumber //エラー
「Value of optional type 'Int' not unwrapped; did you mean to use '!' or '?' ?」というエラーがでます。
「toInt()」でString型をInt型に変換できます。たとえば上記のような"123"はInt型に正しく変換できますが、"Hello, world"などの文字列はInt型に変換できませんよね。そんな場合はnilとして変換されます。
つまり、toInt()で変換された変数は「nilであるかもしれない」のでOptional Valueとなります。
Optional Valueを代入したいときは、代入先をOptionalにしてあげればOKです。
let number = "123" let convertedNumber = number.toInt() var intNumber:Int? = convertedNumber //OK
nilを許容しない変数にOptional Valueを代入したいときはどうすればよいでしょうか。
そこで、オブジェクトが必ずnilじゃない保証があるという前提で、「このオブジェクトはnilではありませんよ」と明示的に宣言するために「!」を使います。
let number = "123" let convertedNumber = number.toInt() var intNumber:Int = convertedNumber! //OK convertedNumberはnilじゃない!
実際はImplicitlyUnwrappedOptional<Int>型になっているようです。
Optionalかどうかを判定する
Optionalかどうかを判定して条件分岐したいときは下記のようにするとよいです。
let number = "123" let convertedNumber = number.toInt() if let actualNumber = convertedNumber { println("\(actualNumber)はnilじゃないです。") }else{ println("nilでした。") }