Optional型とは
Optionalは、値が存在するかどうかを表す型。Swiftでは、安全性を担保するために、原則nil
を許容しない。例外として、nil
を許容する場合、Optional型を使う。
目的
安全性の向上。
「値が存在しない状態(nil
)を明示的に扱える。そうすると、nil
に関連するエラーがコンパイル時に検知できる。
コンパイル時にエラー検知することで、実行時エラー(例えば、値があると思ったが、実際はnilだった)を回避できる。
使い方
ラップ
値がない場合: nil
let noValue: Int? = nil
値がある場合: .someまたは簡略表記
let someValue: Int? = .some(42)
let shorthandValue: Int? = 42
アンラップ
1. 強制
let value: Int? = 42
print(value!) // 42
補足
強制アンラップの多用には注意が必要。Swiftはプログラムのバグをコンパイル時に検出することで安全性を高める設計思想をもつ言語。そのため、強制アンラップの多用はその思想に反してエラー検知を実行時まで先延ばしにすることを意味する。
2. オプショナルバインディング
①if let
let optionalValue: Int? = 42
print(type(of: optionalValue)) // Optional<Int>
if let unwrapped = optionalValue {
print(type(of: unwrapped)) // Int
print("アンラップされた値: \(unwrapped)")
} else {
print("値は存在しません")
}
②guard let
func printValue(_ value: Int?) {
guard let unwrappedValue = value else {
print("値は存在しません")
return
}
print("値は存在します: \(unwrappedValue)")
}
let optionalValue: Int? = 42
printValue(optionalValue) // 値は存在します: 42
let nilValue: Int? = nil
printValue(nilValue) // 値は存在しません
3. デフォルト値を設定
let result = someValue ?? 0
4. オプショナルチェーン
下記のサンプルで、user.address
に値が存在する場合、city
にアクセス。一方、user.address
がnil
の場合、チェーンを中断し、?.city
は実行されず、nil
を返す。nil
を返してもクラッシュしない理由は、オプショナルチェーンの仕様。
struct User {
var name: String
var address: Address?
}
struct Address {
var city: String
var postalCode: String
}
var user = User(name: "John", address: nil)
var cityName = user.address?.city //?.cityは実行されず、チェーンを中断。
print(cityName) // nil(クラッシュしない)
user.address = Address(city: "New York", postalCode: "10001")
cityName = user.address?.city
print(cityName)// Optional("New York")
補足
nil
、Optional()
は、
下記Swiftの標準ライブラリに下記のEnum型が定義されているから使える。
enum Optional<Wrapped> {
case none // nil
case some // 値が存在する
}
let none = Optional<Int>.none
print("none: \(String(describing: none))") //none: nil
let some = Optional<Int>.some(1)
print("some: \(String(describing: some))") //some: Optional(1)
参考:石川 洋資; 西山 勇世. [増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 WEB+DB PRESS plus (p.123). 株式会社技術評論社. Kindle 版. https://amzn.asia/d/i8oLYYp