swift のオプショナルに苦戦した初心者が調べてまとめたものです。
オプショナルって何
値が存在しない変数を宣言するときに使うデータ型をオプショナルという。
変数のデフォルト値がないとき
var dinner: String
print(dinner)
変数 dinner
が宣言されているが、空っぽの状態 nil
のためエラーが発生する。
Variable 'dinner' used before being initialized
変数を宣言したときにあらかじめ値を入れておけばひとまずエラーは発生しないが、宣言時には値を入れておきたくないときにオプショナルを使うとエラーを回避できる。
var dinner: String?
print(dinner)
型の最後に ?
を付けると、オプショナルの String として宣言される。
これにより変数 dinner
では nil
の状態が許容され、エラーは消える。(ただこの場合警告が表示される)
オプショナルに値を入れたとき
var dinner: String?
dinner = "Hamburger"
print(dinner)
// Optional("Hamburger")
オプショナルの変数に値を入れて出力したとき、Optional
に包まれた状態で出力される。
オプショナルをアンラップするには
変数 dinner
を別の文字列に結合したいとき、例えばこのように書いたとする。
var dinner: String?
dinner = "Hamburger"
let text = "I eat a \(dinner) for dinner."
print(text)
// I eat a Optional("Hamburger") for dinner.
結果、変数 dinner
の値がオプショナルに包まれている状態で出力される。
演算子で結合してみた場合、通常の String は演算子を使用してオプショナルと結合できないため、エラーが発生する。
var dinner: String?
dinner = "Hamburger"
let text = "I eat a " + dinner + " for dinner."
print(text)
// Value of optional type 'String?' must be unwrapped to a value of type 'String'
強制アンラップ
オプショナルの文字列を使用する手段として、文字列をアンラップする方法がある。
強制アンラップは、変数に値が含まれているかどうかに関係なく、名前の通り強制的にアンラップする。
var dinner: String?
dinner = "Hamburger"
let text = "I eat a " + dinner! + " for dinner."
print(text)
// I eat a Hamburger for dinner.
値が入っているときはアンラップされるが、もしオプショナルが nil
だった場合はクラッシュする。
オプショナルバインディング
値が nil
だった場合に発生するクラッシュを回避する方法として、オプショナルバインディングが使用できる。
オプショナルバインディングは、オプショナルの値を一時的に別の変数に割り当て、条件分岐によって処理を変える。
これにより、nil
でもクラッシュが発生しない。
var dinner: String?
if let dinnerMenu = dinner {
let text = "I eat a " + dinnerMenu + " for dinner."
print(text)
}
変数 dinner
に値がある場合、 dinnerMenu
に値が割り当てられる。このとき if ステートメントは true
を返すため、ブロック内の処理が実行される。
もし dinner
に値がない場合、 dinnerMenu
に値が割り当てられず、if ステートメントは false
を返すため、ブロック内の処理が実行されない。
オプショナルチェイニング
オプショナルのメソッドやプロパティの値を取得するとき、オプショナルチェイニングを使う。
オプショナルのあとに疑問符 ?
を配置するとオプショナルチェイニングとなる。
struct dinnerMenu {
let menu = "Hamburger"
}
var dinner: dinnerMenu?
print(dinner?.menu)
// nil
変数の値が空っぽのため、結果は nil
となる。
nil 結合演算子
変数を宣言するときに、nil
のときに返すデフォルト値を決めておくことができる。
オプショナルに値が入っているときはアンラップし、nil
のときはデフォルト値を返す。
var dinnerMenu: String?
let dinner = dinnerMenu ?? "variable is empty"
print(dinner)
// variable is empty
nil チェック
if 文を使って、nil
かどうか判定し処理を分岐させる方法もある。
var dinner: String?
if dinner != nil {
print(dinner)
} else {
print("variable is empty")
}
// variable is empty