はじめに
Swiftでは、変数の宣言時になにも値がない状態を許すか許さないかを、データ型で指定する必要がある。オプショナル型はデータ型のひとつ。
オプショナル型とは
値がない状態を許すデータ型が「オプショナル型」で、変数宣言時のデータ型のあとに「?」か「!」を指定する。
「?」か「!」を付けない宣言は、値がない状態を許さない「非オプショナル型」になる。
一般的なオプショナル型は「?」を利用する。
オプショナル型は、変数の宣言と同時に自動で「nil」が代入される。
通常の変数(非オプショナル型)は、変数にnilを代入すると「nil cannot be assigned to type」のエラーとなる。
「?」で宣言したオプショナル変数を利用する場合には、アンラップが必要。
「!」で宣言したオプショナル変数を利用する場合には、アンラップをしなくても使用することができるが、開発者が値を保証する必要がある。
アンラップとは
オプショナル型の変数やメソッドを、安全に取り扱う手法を「アンラップ」という。
アンラップは値がないこと「nil」をチェックして使う方法とチェックせずに使う方法がある。
チェックして使う方法は、「if let ~」「guard let ~」を利用する。
チェックせずに使う方法は、強制アンラップといい「!」を記述する。
強制アンラップは、開発者が値があると分かっているときに使う。
オプショナル型の使い方
オプショナルは先述したとおり「nil」を代入できるため、オプショナルで宣言した変数が「nil」であっても参照できる。
// オプショナル型の宣言
var hoge: String?
var fuga: Int!
print(hoge) // 実行結果 => nil
print(fuga) // 実行結果 => nil
非オプショナル型の場合は、変数の値にnilを代入するとエラーが発生する。
// 非オプショナル型の宣言
var name: String
name = nil // 実行結果 => エラー(nil cannot be assigned to type ~)
オプショナル型と非オプショナル型は同じように変数の操作をすることができない。
var num1: Int = 1
var num2: Int? = 2
print(num1 + 1); // 2
print(num2 + 1); // エラー(value of optional type 'Int?' not unwrapped; did you mean to use '!' or ‘?’?)
オプショナル型の変数の値がnilでないことを明示するためにアンラップする必要がある。
アンラップするためには、オプショナル型の変数の後ろに「!」を付ける。
// オプショナル型を宣言
var num: Int?
num = 100
print("num:\(num!)") // 実行結果 => num:100
上記のように「!」でアンラップすれば安全に値を参照することができる。
オプショナル型の変数の値が「nil」の場合は、アンラップするとエラーになるので注意が必要。
オプショナル型を比較
オプショナル型を用いて比較することをバインディング(Binding)という。
//オプショナル型の宣言
var num: Int?
//Binding
if let sum = num {
print("sum:\(sum)")
} else {
print("値が設定されていません。") // 実行結果 ⇒ 値が設定されていません。
}
暗黙的なオプショナル型
オプショナル型は宣言時に型の後ろに「?」を付けるが、
暗黙的なオプショナル型を宣言するときには、型の後ろに「!」を付ける。
オプショナルを暗黙的に宣言すると、使用時にアンラップする必要がない。
そのため、初期値はnilでも使うときには値が格納されていることがわかっているときには、
暗黙的なオプショナル型を宣言したほうが安全。
しかし、暗黙的なオプショナル型でも値がnilでアンラップが必要なときに、
そのまま使用するとエラーになるので注意。
//暗黙的なオプショナル型の宣言
var num: Int!
print(num) // null
num = 100
print(num) // 100
num = nil
print(num + 10) // エラー
まとめ
Swiftを使うならオプショナル型は、かなり必須な知識だと思った。
調べていて最初の壁のように感じたが、開発する上でほぼ必ず使う知識になるので、
使っているうちに理解できていくものだと思った。
実際にコードを書く際に使用し、理解を深めていきたい。