読者です 読者をやめる 読者になる 読者になる

うさがにっき

読書感想文とプログラムのこと書いてきます

Swiftにおけるoptionalに使われる「?」「!」の2つの意味

概要

以前optionalについてまとめた
Optionalについて - うさがにっき

SwiftにおけるOptionalに使われる「?」「!」には二つの使い方があったのでそれをまとめる

詳細

Optionalの扱いの復習

swiftでは通常に変数を宣言するとnilを入れることができない

class Dog {
    func bark() -> String {
        return "Wan!"
    }
}

var dog:Dog = nil // コンパイルエラー

swiftではnilを入れる変数を宣言する場合、Optinal型変数として宣言する必要がある

var dog:Dog? = nil

Optional型変数として宣言したインスタンスは、通常の変数とは違うためそのままでは中のメソッドを呼び出せない

var dog:Dog? = Dog()

println(dog.bark()) //エラー

Optinal型変数は!をつけることにより、Optinalから通常の変数にアンラップできる
これによりメソッドを呼び出せる

var dog:Dog? = Dog()

println(dog!.bark())

「?」の二つの使い方

  • Optinal型変数の宣言

Optional型の実態はOptional

var dog: Dog? = nil
  • optinal chainning
var dog:Dog? = Dog()

println(dog?.bark()) // 取得されるのはString?型

optional変数?.メソッド
で呼び出すことによりoptional型変数を返り値として取得できる
これをoptional chainingという

「!」の二つの使い方

  • Optional変数のアンラップ
var dog:Dog? = Dog()

println(dog!.bark())

ちなみにoptional bindingを使うことによってアンラップすることもできる

if var unwrappedDog = dog {
    println(unwrappedDog.bark())
}
if let unwrappedDog = dog {
    println(unwrappedDog.bark())
}
white var unwrappedDog = dog {
    println(unwrappedDog.bark())
}

更に比較演算子を使うと自動的にアンラップされる

var wrappedInt: Int? = 1 // Optional 型

println(wrappedInt == 1) // 自動的にアンラップされてtrueが返る
  • Implicitly Unwrapped Optional 型

「Implicitly unwrapped optional 型」 とは、「自動的にアンラップされる optional 型」のこと
初期値はnil
nilを実行しようとすると実行時エラーとなる
Implicitly unwrapped optional 型の実態はImplicitlyUnwrappedOptional

var iwrappedDog: Dog! //初期値はnil
iwrappedDog = Dog()

println(iwrappedDog.bark()) // 自動的にアンラップされて実行できる

Implicitly Unwrapped Optional 型にはoptional型を代入できる

var iwrappedDog: Dog! = Dog()
var wrappedDog: Dog? = Dog()

iwrappedDog = wrappedDog
println(iwrappedDog.bark())

更に非Optional型も代入できる

var iwrappedDog: Dog! = Dog()
var dog: Dog = Dog()

iwrappedDog = dog
println(iwrappedDog.bark())