質問の背景:
オプショナルチェイニングは、Swift でネストされたオプショナルの便利な取り扱いのために導入されました。これにより、nil の確認を無限に行うことなく、コンパクトで安全なコードを書くことができます。特に、存在しないかもしれないオブジェクトのプロパティやメソッドにアクセスする際に便利です。
問題:
オプショナルチェイニングを使用していると、もしチェーン内のオブジェクトが nil であった場合、どのような結果が得られるかを誤解しやすいです。また、返される値を誤って処理すると、実行時エラーや予期しない動作に直面する可能性があります。
解決策:
オプショナルチェイニングは、nil である可能性のあるオブジェクトのネストされたプロパティ、メソッド、サブスクリプトに安全にアクセスするためのメカニズムです。チェーンのいずれかの要素が nil であれば、全体の構造は nil を返し、エラーは発生しません。
コードの例:
class Address { var city: String? } class User { var address: Address? } let user: User? = User() user?.address?.city = "モスクワ" if let city = user?.address?.city { print(city) } else { print("都市が見つかりません") }
主な特性:
オプショナルチェイニングを使用してメソッドを呼び出す、またはプロパティを取得する際、オブジェクトが nil の場合、実行時エラーが発生しますか?
いいえ、実行時エラーは発生しません。オプショナルチェイニングを介したすべての式は nil を返し、エラーなしで実行が中断されます。
コードの例:
let email: String? = nil let lowercased = email?.lowercased() // lowercased は nil となり、エラーは発生しません
中間オブジェクトが存在しない場合、オプショナルチェイニングを介しての代入は実行されますか?
いいえ、オブジェクトまたは中間プロパティが nil であれば、代入は何も影響せず、メモリは変更されません。
コードの例:
var user: User? = nil user?.address?.city = "カザン" // 何も起こらず、user は nil
オプショナルチェイニングの結果は非オプショナルになることがありますか?
いいえ、オプショナルチェイニングを介した表現の結果は常にオプショナルです。元のプロパティがオプショナルでなくても同様です。
コードの例:
class Test { var number: Int = 10 } let t: Test? = nil let value = t?.number // value: Int? (オプショナル)
コード内で user?.address?.city にアクセスし、都市の存在確認をせずに city! を直接出力します。これにより、どれかの要素が nil であればクラッシュします。
利点:
欠点:
コード内で if let または guard let を使用して user?.address?.city の存在を確認し、値を操作します。
利点:
欠点: