Swiftのオプショナル型がよく分からない人へ

みなさん、こんにちは。
新しいメガネが欲しい渋谷です。
今回はSwift初心者がハマりやすいであろうオプショナル型
についての基本を書いていこうと思います。
Xcodeに言われるがままに変数に!
や?
を付けたり、Fix
を押している人がいるのではないでしょうか。
これを読んで少しでもそのような人やFix
を押す機会が減ればいいなと思っています。
オプショナル型とは
オプショナル型は、変数や定数に予期しないnilが入る事を避けるために使われる変数の型です。
オプショナル型にはオプショナル型
と非オプショナル型(Int型、String型など)
があり、2つの違いを簡単に説明すると以下のようになります。
- オプショナル型・・・変数にnilを代入できる
- 非オプショナル型・・・変数にnilを代入できない
オプショナル型の宣言
変数(定数)の宣言時や初期化時に、オプショナル型なのか非オプショナル型なのかを指定できます。
方法は、変数(定数)名やその型の後ろに!
か?
を付けるだけです。
// オプショナル型の宣言
var name: String?
var age: Int!
// 非オプショナル型の宣言
var gender: String
※ 上記の例のvar name: String?
はvar name: Optional<String>
と書き換えることができます。
この段階でオプショナル型で宣言したname
とage
を出力すると、下記のようにnil
が出力されているのがわかります。
では、非オプショナル型で宣言したgender
はどうなるか見てみると、下記のようにコンパイルエラーが起こり実行できません(warningは気にしないで下さい)。
これは、非オプショナル型のgender
がnil
だからです。試しに下記のようにgender
に値を入れて初期化すると、問題なく動作します。
“!” と “?” の違い
オプショナル型を宣言する時に用いる!
と?
ですが、当然ながら違いがあります。
一般的には?
をオプショナル型と言い、!
は暗黙的オプショナル型と言います。
違いを見てみましょう。num1
とnum2
の足し算を例とします。
■暗黙的オプショナル型
10 + 20
の計算結果として30
が出力されています。
■オプショナル型
オプショナル型は、コンパイルエラーが起こってしまい計算できません。エラーが起こる理由は、num1
とnum2
を出力すれば分かります。
はい、Optional()
で囲われているのが分かりますね。
このように、暗黙的オプショナル型は使用する際に自動的にOptional()
が外れてくれるのに対し、オプショナル型は外してくれないという点で異なっています。
一見、暗黙的オプショナル型の方が便利なように感じますが、変数を使用する際にnil
が入ってしまっていると実行時にエラーが起こってしまうので注意が必要です。
ちなみに、Optional()
を外す処理をunwrapと言います。
オプショナル型のunwrap
オプショナル型をunwrapする方法はいくつかあるのですが、今回は3つほど紹介します。他の良い方法を知っている方がいれば教えてください。
1. forced unwrapping
その名の通り、強制的にunwrapします。使い方は変数の後ろに!
を付けるだけですが、暗黙的オプショナル型と同じようにnil
が入っていると実行時にエラーが起こってしまうので注意が必要です。
2. Optional-Binding
条件分岐を使って変数がnil
かどうか見分ける方法です。下記の例だと、オプショナル型の変数name
に"吾輩"
を代入していてname
がnil
ではないので、定数neko
にname
の値が代入され、String型
で"吾輩"
と出力されています。
name
に何も代入せずnil
のままだと、名前はまだない。
が出力されます。
3. guard-let構文
Optional-Bindingと似ていますが、これは変数がnil
だった時に処理を中断させる時に使います。
まとめ
- オプショナル型には
nil
が代入できる - 非オプショナル型には
nil
が代入できない - オプショナル型は変数(定数)宣言時や初期化時に変数名の後ろに
!
や?
を付けて使用する - 暗黙的オプショナル型(
!
)は変数(定数)使用時に自動でunwrapされる - オプショナル型(
?
)はunwrapしないとString型
やInt型
としては使えない。