Swift オプショナル(Optionals)型

Swift のオプショナル(Optional)型は、値が欠落している場合を処理するために使われます。オプショナルは「そこに値があり、それが x に等しい」または「そこに値がない」ことを表します。

Swift言語では、後置 ? は名前付き型 Optional の略記として定義されています。言い換えると、以下の2つの宣言は等しいです:

var optionalInteger: Int?
var optionalInteger: Optional<Int>

どちらの場合も、変数 optionalInteger はオプショナル整数型です。注意:型と?の間にスペースはありません。

Optional は2つのケース None と Some(T) を持つ列挙型であり、値があるかもしれないし、ないかもしれないことを表します。あらゆる型は明示的にオプショナル型として宣言(または暗黙的に変換)できます。オプショナル型を宣言するときは、括弧を使って ? 演算子に適切なスコープを与えるようにしてください。例えば、オプショナル整数配列を宣言する場合は (Int[])? と書くべきで、Int[]? と書くとエラーになります。

オプショナル変数またはオプショナルプロパティを宣言するときに初期値を指定しない場合、その値はデフォルトで nil になります。

オプショナルは LogicValue プロトコルに準拠しているため、ブール環境に置くことができます。この場合、オプショナル型 T? が型 T の何らかの値(つまりその値が Optional.Some(T) である場合)を含んでいれば、このオプショナル型は true と等しく、そうでなければ false です。

オプショナル型のインスタンスが値を含んでいる場合、後置演算子 ! を使ってその値にアクセスできます。次のようになります:

optionalInteger = 42
optionalInteger! // 42

演算子!を使って値が nil のオプショナル変数を取得すると、実行時エラーになります。

オプショナルチェーンとオプショナルバインディングを使うと、オプショナル式に対する操作を選択的に実行できます。値が nil の場合、どの操作も実行されず、実行時エラーも発生しません。

以下の例を詳しく見て、Swift でのオプショナル型の用途を理解しましょう。

import Cocoa

var myString:String? = nil

if myString != nil {
    print(myString)
}else{
    print("字符串为 nil")
}

上記のプログラムの実行結果は次のとおりです:

字符串为 nil

オプショナル型は Objective-C のポインタの nil 値に似ていますが、nil はクラス(class)にのみ有効です。一方、オプショナル型はすべての型に対して使用でき、より安全です。


強制アンラップ

オプショナル型が実際に値を含んでいると確信できる場合、オプショナルの名前の後に感嘆符(!)を付けて値を取得できます。この感嘆符は「このオプショナルには値があると分かっているので、それを使ってください」という意味です。これはオプショナル値の強制アンラップ(forced unwrapping)と呼ばれます。

例は次のとおりです:

import Cocoa

var myString:String?

myString = "Hello, Swift!"

if myString != nil {
   print(myString)
}else{
   print("myString 值为 nil")
}

上記のプログラムの実行結果は次のとおりです:

Optional("Hello, Swift!")

オプショナル値を強制アンラップするには、感嘆符(!)を使います:

import Cocoa

var myString:String?

myString = "Hello, Swift!"

if myString != nil {
   // 强制解析
   print( myString! )
}else{
   print("myString 值为 nil")
}

上記のプログラムの実行結果は次のとおりです:

Hello, Swift!

注意:
使用!存在しないオプショナル値を取得すると実行時エラーになります。使用!強制アンラップを行う前に、必ずオプショナルが非nilの値を含んでいることを確認してください。


自動アンラップ

オプショナル変数を宣言するときに、疑問符(?)の代わりに感嘆符(!)を使うことができます。そうすると、オプショナル変数は使用時に感嘆符(!)を追加して値を取得する必要がなくなり、自動的にアンラップされます。

例は次のとおりです:

import Cocoa

var myString:String!

myString = "Hello, Swift!"

if myString != nil {
   print(myString)
}else{
   print("myString 值为 nil")
}

上記のプログラムの実行結果は次のとおりです:

Hello, Swift!

オプショナルバインディング

オプショナルバインディング(optional binding)を使用して、オプショナル型が値を含んでいるかどうかを判断し、含んでいる場合はその値を一時的な定数または変数に代入します。オプショナルバインディングは if 文や while 文で使用して、オプショナル型の値を判定し、定数または変数に代入することができます。

if 文では次のようにオプショナルバインディングを記述します:

if let constantName = someOptional {
    statements
}

簡単なオプショナルバインディングの例を見てみましょう:

import Cocoa

var myString:String?

myString = "Hello, Swift!"

if let yourString = myString {
   print("你的字符串值为 - \(yourString)")
}else{
   print("你的字符串没有值")
}

上記のプログラムの実行結果は次のとおりです:

你的字符串值为 - Hello, Swift!
その他の拡張