Objective-C から iOSアプリの開発を始めた人でも Swift に慣れるにはそれなりにコストがかかります。
Swift を学び始めて誰もが最初に気づく Objective-C との違いは、変数の後に付く ? や !(Optional変数)だと思います。
今回はこの Optional について自分なりにまとめてみようと思います。
optional について
まず最初に、Optional というのは型です。Int の Optional型、String の Optional型、といった表現をします。
変数の型が Optional かそうでないかの違いは、変数に nil が入る(もしくは入るかもしれない)か、そうでないかの違いとなります。
このように Optional は nil が入る(かもしれない)値を明示的にする目的で使用されます。
Optional の宣言
Optional の宣言は ? で宣言する方法と ! で宣言する方法があります。
[code]
var exclamationStr: String! = “Optional”
var questionStr: String? = “Optional”
[/code]
両者の違いは次項で説明するアンラップに関係します。
? は一般的な Optional 型
! は暗黙的にアンラップされる Implicitly Unwrapped Optional 型
で、この2つは同じ Optional 型のように扱われがちですが、全然別物です。
はじめに言っておくと ! は特別なことがない限り使用しないほうがいいです。
Optional のアンラップ
Optional 型から値を取り出すことをアンラップするといいます。 Optional のアンラップにはいくつか方法があります。
フォースド・アンラッピング (Forced Unwrapping)
読んだ意味そのまま、強制的に値を取り出す方法で ! を使用し値を取り出します。
[code]
var optionalStr: String? = “Optional”
println(optionalStr!) // Forced Unwrapping
[/code]
Optional 変数を通常の変数のように、そのまま出力しようとするとエラーになります。
[code]
var optionalStr: String? = “Optional”
println(optionalStr) // fatal error
[/code]
Optional 変数が nil だった場合にもエラーとなります。
[code]
var optionalStr: String? = “Optional”
optionalStr = nil
println(optionalStr!) // fatal error
[/code]
オプショナル・チェインニング (Optional Chaining)
? を使用し値を取り出します。
[code]
var optionalStr: String? = “Optional”
println(optionalStr?) // “Optional”
[/code]
値が nil だった場合は nil を返します。
[code]
var optionalStr: String? = “Optional”
optionalStr = nil
println(optionalStr?) // nil
[/code]
オプショナル・バインディング (Optional Binding)
Optional 型の変数を代入された変数が、非 Optional 型になることを利用しアンラップする方法です。
[code]
var optionalStr: String? = “Optional”
if let string = optionalStr {
// Optional Binding
println(string) // “Optional”
}
[/code]
上記の例の場合、if で string に値が代入できるイコール optionalStr が nil ではない、という意味となるため、もし optionalStr が nil の場合は println は実行されません。冗長にも思われますが、オプショナル・バインディングを使用すると nil を意識したコーディングとなります。
暗黙的アンラップ (Implicitly Unwrapped Optional)
冒頭で述べた ! で宣言をおこなった値は暗黙的にアンラップされます。
[code]
var optionalStr: String! = “Optional”
println(optionalStr) // “Optional”
[/code]
値が nil の場合にはエラーとなります。
[code]
var optionalStr: String!
println(optionalStr) // fatal error
[/code]
このように Implicitly Unwrapped Optional で宣言すると、一見して普通の変数のように扱えるため、Optional に対しての理解がないと ! を乱用してしまいがちです(自分はそうでした)。
ただ、これでは Optional を使用するメリットである nil が入る(かもしれない)値を明示的にする、という意味がなくなってしまいます。
! での Optional 宣言は、オブジェクトの初期化のときに「どうしても初期値が nil でなければいけない場合」にのみ使用するものとなります。
宣言時は nil にするしかないが、宣言後には常に何かの値が入っていることを前提とした場合にのみ ! (Implicitly Unwrapped Optional) で宣言すればよいでしょう。
まとめ
Optional は 基本的には ? を宣言し使用することで、Optional の目的である nil を意識したコーディングが行え、コンパイラの nil 値のチェックが容易になります。
nil を返す(かもしれない)関数の戻り値を処理する場合はオプショナル・バインディングのように、まず Optional 変数で受け取り、Optional のラッピングを解いて処理をする という使い方ができるようになります。
Optional 型に慣れるまではコーディング中やビルド時に、幾度と無くエラーとなってしまいますが、そのほとんどは Xcode が自動で対処(サジェスト)してくれるため、まずはガンガン使ってみるのが一番の習得方法だと思います。
この記事がみなさんのお役に立ちましたら、下記「Share it」よりブックマークやSNSで共有していただければ幸いです。