SwiftにOptionalという型があります。
Optional型は値がある、又は、値がない場合に用いる型です。
今回はOptionalの動作確認のための簡単なプログラムを
日々大量のバグを生み出し続けるWebプログラマー「エイチ」と
バグが大好物なエイチのペット「バグバグ」とともに実装してみます。
バグバグ 「・・・」
エイチ 「バグバグ ねぇ バグバグ 起きなよ
SwiftにOptionalってのがあるぞ
なんだこれ? バグバグ知ってる?
ちょっと試してみよっと」
バグバグ 「!!」
エイチ 「まずはInt型とInt?型を宣言してみよっと」
var valueInt: Int // OptionalでないInt型の変数を宣言
var valueOptionalInt: Int? // OptionalであるInt?型の変数を宣言
エイチ 「よしっ 変数の中身を見てみよっと」
print("valueInt: \(valueInt)")
print("valueOptionalInt: \(valueOptionalInt)")
エイチ 「およよ? エラーになっちゃったよ」
バグバグ 「!!」(バグバグの体は熱くなっているようだ)
error: variable 'valueInt' used before being initialized
エイチ 「Int型の変数valueIntを初期化しないといけないんだね
自動的に0に初期化してくれないんだ 1に初期化しよっと」
var valueInt: Int = 1 // OptionalでないInt型の変数を宣言時に1に初期化
var valueOptionalInt: Int? // OptionalであるInt?型の変数を宣言
print("valueInt: \(valueInt)")
print("valueOptionalInt: \(valueOptionalInt)")
エイチ 「今度はちゃんと出力されたぞ」
valueInt: 1
valueOptionalInt: nil
エイチ 「OptionalのInt?型の変数valueOptionalIntは
自動的にnilに初期化されるんだ
変数valueOptionalIntも初期化してみよっと」
var valueInt: Int = 1 // OptionalでないInt型の変数を宣言時に1に初期化
var valueOptionalInt: Int? = 2 // OptionalであるInt?型の変数を宣言時に2に初期化
print("valueInt: \(valueInt)")
print("valueOptionalInt: \(valueOptionalInt)")
エイチ 「およよ? 変数valueOptionalIntの出力が2じゃない
nilのときは出力されてたのに」
valueInt: 1
valueOptionalInt: Optional(2)
エイチ 「よしっ Forced Unwrappingの出番だ
Optionalの変数valueOptionalIntの後ろに!を付けて参照だ」
print("valueOptionalInt: \(valueOptionalInt!)")
valueOptionalInt: 2
エイチ 「Optionalの変数の値を参照するときは
Forced Unwrappingしなといけないんだね
nilのときはForced Unwrappingしてなかったのに・・・
試してみよっと」
var valueOptionalInt: Int? = nil // OptionalであるInt?型の変数を宣言時にnilに初期化
print("valueOptionalInt: \(valueOptionalInt)")
print("valueOptionalInt: \(valueOptionalInt!)")
エイチ 「およよ? またエラーになっちゃったよ」
バグバグ 「!!」(バグバグの体はまた熱くなっているようだ)
valueOptionalInt: nil
fatal error: unexpectedly found nil while unwrapping an Optional value
エイチ 「Forced UnwrappingはOptionalの中身がnilのときは使えないんだ
ってことはOptionalの値を参照するときは
if文でnilチェックしなとダメかな」
var valueOptionalInt: Int? = nil // OptionalであるInt?型の変数を宣言時にnilに初期化
if valueOptionalInt != nil {
print("valueOptionalInt: \(valueOptionalInt!)")
} else {
print("valueOptionalIntはnilだよ")
}
valueOptionalIntはnilだよ
var valueOptionalInt: Int? = 2 // OptionalであるInt?型の変数を宣言時に2に初期化
if valueOptionalInt != nil {
print("valueOptionalInt: \(valueOptionalInt!)")
} else {
print("valueOptionalIntはnilだよ")
}
valueOptionalInt: 2
エイチ 「Optionalかどうかによって 変数を参照するときに
!を付けたり付けなっかたりするんだ
なんか混乱しそう・・・
Optional Bindingにしたほうがいいのかな
こっちは!を付けずにOptionalを参照したようにみえるぞ」
var valueOptionalInt: Int? = 2 // OptionalであるInt?型の変数を宣言時に2に初期化
if let tempValue = valueOptionalInt {
print("valueOptionalInt: \(tempValue)")
} else {
print("valueOptionalIntはnilだよ")
}
valueOptionalInt: 2
エイチ 「初期化後にOptionalの値が変わらないなら
Implicitly Unwrapped Optionalってゆーのもあるのか
!なしで参照できるし」
let valueOptionalInt: Int! = 2 // Implicitly Unwrapped OptionalであるInt!型の定数を宣言時に2に初期化
print("valueOptionalInt: \(valueOptionalInt)")
valueOptionalInt: 2
エイチ 「Optionalってなんだかややこしい・・・
Optional 好きになれるかな」
エイチ 「さあ バグバグ ソースコード 全部お食べ」
バグバグ 「バグバグ バグバグ バグバグ」
エイチ 「美味しかったろう バグバグ」