やんまメモ

アプリやWeb開発などのことを適当に書いていきます。

Swiftのオプショナル関係をコード中心でまとめてみた

使っていると素敵なSwiftのオプショナル……なのですが、色々あってよくどう書くんだっけと忘れてしまうので、コードを中心に個人的メモとしてまとめておきます。

コードは基本的にSwift2.1想定で書いています。

Optionalとは

この辺の解説が非常に詳しくてわかりやすいです。

どこよりも分かりやすいSwiftの"?"と"!" - Qiita

宣言

通常の型に ? をつけることで各型をラップしたオプショナルとして変数・定数を宣言できる。

var object: Int? // 初期値を指定しない場合、初期値はnilになる
var object2: Optional<Int> //これも上と同じ意味合い

比較演算子を使う際は、特に意識なく使用することができるが、実際に値を取り出したりオブジェクト内関数を使用するためには以下のアンラップが必要になる。

オプショナルのアンラップ方法

オプショナルバインディング

確実にアンラップした値を処理したり、nilの場合の処理を書けるので嬉しい。

スコープの扱いはちゃんとしないといけないが、guard構文を使えばネストも浅くなって素敵。

var str: String?

// if letは右辺をアンラップできる場合に左辺に代入し、スコープ実行する
if let str = str {
    // strはnilのため、このスコープは実行されない
    print(str)
}

str = "hoge"
if let str = str {
    // アンラップされstrはString型となる
    print(str)
}

func hoge() {
  guard let str = str else {
      return // strがnilならここで処理を終える
  }
  // guard構文でアンラップされているため、
  // 以降strはString型になる
  print(str)
}

hoge()

オプショナルチェイニング

nilじゃなければ次へ、というのを繰り返して、目的のブツを手に入れたり、関数を実行したりできる。

途中にnilが挟まるとプロパティならnilが返され、関数は実行されないため、ちゃんとする必要がある。

internal class Hoge {
    var butsu = "ブツ"
    func hoge() {
        print("hoge")
    }
}

var object: Hoge?
object?.hoge() // objectがnilなので、関数は実行されない
print(object?.butsu) //objectがnilなので取得される値はnilとなり、「nil」と表示される

object = Hoge()
object?.hoge() // objectに値が入ったので、関数は実行される
print(object?.butsu) //「Optional("ブツ")」と表示される

// 値だけ表示する場合には
// オプショナルバインディングと組み合わせる
if let butsu = object?.butsu {
    print(butsu)
}

Nil Coalescing Operator

名前などをオプショナルで宣言しておいて、 未入力(=nil)なら「名無し」と出すとかがスマートに書ける。

var str: String?
// 値が入っていればstr、nilなら「なし」が代入される
let display_text = str ?? "なし" // この場合「なし」が代入される

強制アンラップ

静的解析とかでよく怒られる奴。

確実に値が入っている状況など使用範囲を狭くしないとオプショナルの恩恵が薄れる。

var str: String?
// print(str!) // Stringを取り出そうとするが、nilなので不正終了
str = "hoge"
print(str!) // Stringを取り出して表示

おわりに

いわゆる「ぬるぽ」に悩まされることもなく、ビルド時に即エラーを出してくれるので非常に頼もしい相棒オプショナル。

Swift自体もまだ発展する言語ですし、まだ勉強中でもあるので、もっともっと便利に使いたいところです👍

もし他にもこんなのあるよ! とか、ここ間違っているよ! というのがあれば、ぜひ教えて下さい!