2015年7月4日土曜日

SwiftのOptional型とは(Optional Value/Optional Type)

Swiftでは、String型などの変数にnilを設定できなくなりました。
Objective-Cから移行してきた人には一見不便に感じますが、nilアクセスによるクラッシュが防げるようになり、プログラムの安全性は上がったと言われています。

とはいえ、nilを設定したい場合もありますよね?
そんな時に使うのがOptional型です。
String型などをOptional型にラップすることで、nilを設定できるようになります。

Optional型の宣言方法

書き方としては、変数の型の後ろに"?"や"!"をつけて宣言します。
String型などをOptional型にラップするので、型指定は必須です。

Optional?はシンタックスシュガーである

要するにString?は、String型をOptional型にラップした型を読み書きしやすくしたもの。
  • Optional型のString型 = String? = Optional<String>
  • 暗黙的Optional型のString型 = String! = ImplicitlyUnwrappedOptional<String>
  • 非Optional型のString型 = String

Optional型の代入

Optional型の変数を非Optional型の変数に代入する場合は、構文エラーになるので注意。
非Optional型はnilを許容しないという原則のためですね。


Optional型のメソッド呼び出し

上記から分かる通り、String?はString型とは異なりOptional型にラップされている状態なので、そのままString型の関数を使おうとすると構文エラーになってしまいます。
そんな場合は、非Optional型にアンラップしてから関数を使用すれば大丈夫です。
アンラップの方法は以下の4通りあります。

  1. Optional Chaining
    変数の後ろに"?"をつけてアンラップする方法
    戻り値がOptional型のため、nilの場合はnilを返します。
  2. Forced Unwrapping
    変数の後ろに"!"をつけて、強制的にアンラップする方法
    戻り値が非Optional型のため、nilの場合は実行時エラーになります。
  3. Implicitly Unwrapped Optional
    暗黙的にアンラップする宣言方法
    変数の型の後ろに"?"ではなく、"!"をつけて宣言します。
    アンラップは暗黙的に行われるので、代入する場合に"?"や"!"をつける必要がなく、String型の関数もそのまま使えます。
    戻り値が非Optional型のため、nilの場合は実行時エラーになります。
  4. Optional Binding
    if文などの条件式で宣言して、Optional型の変数を代入してアンラップする方法
    代入された値がnilかどうかで処理を分岐できます。

"!"の場合、クラッシュさせないため、従来のようにnilチェック処理が必須になってきます。
そもそも宣言時以外にnilが入る可能性がある変数には、"?"を使用するのが良さそうです。

Nil Coalescing Operator

オプショナル型がnilの時にデフォルト値を入れたい場合は、"??"の演算子を利用すると便利そうです。
"??"の左にoptional型の変数、右にはその値がnilだった時に返したい値を書きます。

冒頭でSwiftは安全性が高いと言いましたが、結局はプログラマ次第なのかな?と思いました。
意味がわかってなくても"!"で書けば、今まで通り変数にnilが入れられるので、乱用すれば今まで通りnilアクセスでクラッシュするような。。
書いてる段階でより明確に意識させられるようになった感じですね。ふむふむ。

0 件のコメント:

コメントを投稿