安全呼び出しオペレーター '?.' は、Kotlinにおけるnull値との対処に関する重要なツールの一つであり、潜在的に欠落している値との作業の安全性と使いやすさを向上させることを目的とした言語の思想の進化として登場しました。
問題の背景: Javaでは、null値はしばしばエラー(NullPointerException)の原因となります。Kotlinはnullableおよびnot-nullable変数を明示的に区別する厳格な型システムを導入し、使いやすいツールを提供しました。
問題: nullの可能性があるオブジェクトと作業する際に、NullPointerExceptionを避けつつ、コードの可読性や簡潔さを損なわずにどうするか?
解決策: オペレーター '?.' を使用することで、nullable変数のプロパティやメソッドに優雅にアクセスできます。オブジェクトがnullでない場合は呼び出しが行われ、nullの場合はnull(または必要なロジックが続く)を返します。
コード例:
val user: User? = getUser() val name = user?.name // user != null の場合は user.name、そうでなければ null user?.printInfo() // user != null の場合に printInfo() が呼ばれる
主な特長:
安全呼び出しオペレーター '?.' を代入の左側で使用できますか?
いいえ。オペレーター '?.' はプロパティや変数の安全な値の設定には使用できず、アクセスや呼び出しのためにのみ使用されます。次のコードは無効です:
user?.name = "Alex" // コンパイルエラー
プロパティの代入は明示的なチェックを通じて安全に行うことができます:
user?.let { it.name = "Alex" }
安全呼び出しオペレーターのチェーンは、最初のnullに出会ったときに何を返しますか?
チェーンの要素の一つが '?.' でnullの場合、式の結果はnullとなり、以降の安全呼び出しは実行されません。
例:
user?.address?.zipCode // userまたはaddressがnullの場合、結果はnull
Unitを返す関数と安全呼び出し '?.' を使用できますか?
はい、オブジェクトがnullでない場合は呼び出しが行われますが、オブジェクトがnullの場合はUnitの代わりにnullが返されます。
例:
user?.clearData() // userがnullの場合、何も起こりません
開発者が長い安全呼び出しチェーンの後にnullの可能性があるところで '!!' を適用します:
val country = user?.address?.city?.country!!
利点:
欠点:
Elvisオペレーターと併用して安全呼び出しを使用し、デフォルト値を返します:
val country = user?.address?.city?.country ?: "Unknown"
利点:
欠点: