Optional型は完全に理解したつもりでしたが、Implicitly Unwrapped Optional(暗黙的アンラップ)についてよくわかってなかったので、備忘で書きます。
フォースアンラップはよく使います。
let hoge: String?
hoge = "!!!"
print(hoge!) //!!!
これはわかりやすい(というかわかってる人に対する記事としてこれを書いています)と思うのですが、
変数の型に、!をつけるとどうなってしまうのでしょうか?
let hoge: String!
Implicitly Unwrapped Optional
?と!という記号は、なんか全部Optional型に関係するものなのですが、
使う方法によってそれぞれ名前がついていて、若干挙動が違ったりします。
正確なところが知りたければ、Swiftの公式ドキュメントを参照するとよいでしょう。
Implicitly Unwrapped Optionals
String?はOptional(String)のSyntax Sugarですが、String!はちょっと違います。
型としてはOptional型になりますが、Implicitly Unwrapped Optional(暗黙的アンラップ)という属性がつき、下記の特徴を持ちます。
- 取り出し時に必ずフォースアンラップされる
- 従ってnilの場合実行時エラーになる可能性がある
サンプルコードとしては下記です。
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark
String?だと取り出し時に!をつけてフォースアンラップしていますが、
Implicitly Unwrapped Optionalだと、フォースアンラップがデフォルトなので、!なしでフォースアンラップとなります。
if let〜やguard let〜を使って、安全に取り出すことも可能です。
if let definiteString = assumedString {
print(definiteString)
}
// Prints "An implicitly unwrapped optional string."
なるほどですね〜!
修正
【Swift 4.2】Implicitly Unwrapped Optional(IUO)が再実装されたらしいので Xcode で試した
コメント欄で指摘頂いたんですが、Implicitly Unwrapped OptionalはSwift4.2以降では型ではなくて、属性に格下げされてました。
そのため本文も修正しました。