Kotlinのヌルセーフティに関する包括的なガイド
1. 概要
この記事では、Kotlin言語に組み込まれているnullの安全機能について説明します。 Kotlinは、null許容フィールドの包括的でネイティブな処理を提供します。追加のライブラリは必要ありません。
2. Mavenの依存関係
開始するには、 kotlin-stdlib Maven依存関係をpom.xml:に追加する必要があります。
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.1.1</version>
</dependency>
最新バージョンはMavenCentralにあります。
3. ヌル可能およびヌル不可能な参照型
Kotlinには、コンパイル時にプログラムの正確性に関する情報をプログラマーに提供するためにコンパイラーによって解釈される2種類の参照があります。null許容型とそうでないものです。
デフォルトでは、Kotlinは値をnullにすることはできないと想定しています。
var a: String = "value"
assertEquals(a.length, 5)
nullを参照aに割り当てることはできません。割り当てようとすると、コンパイラエラーが発生します。
null許容型の参照を作成する場合は、型定義に疑問符(?)を追加して作成する必要があります:
var b: String? = "value"
その後、nullを割り当てることができます。
b = null
b参照にアクセスする場合、コンパイルエラーを回避するためにnullケースを明示的に処理する必要があります。Kotlinはこの変数がnullを保持できることを知っているためです。
if (b != null) {
println(b.length)
} else {
assertNull(b)
}
4. 安全な通話
このような方法ですべてのnull許容参照を処理するのは面倒な場合があります。 幸い、Kotlinには「安全な呼び出し」の構文があります。この構文により、プログラマーは特定の参照がnull以外の値を保持している場合にのみアクションを実行できます。
この機能を説明するために、2つのデータクラスを定義しましょう。
data class Person(val country: Country?)
data class Country(val code: String?)
countryおよびcodeフィールドはnull許容参照型であることに注意してください。
これらのフィールドに流暢にアクセスするために、安全な呼び出し構文を使用できます。
val p: Person? = Person(Country("ENG"))
val res = p?.country?.code
assertEquals(res, "ENG")
変数pがnullを保持している場合、セーフコール構文はnullの結果を返します。
val p: Person? = Person(Country(null))
val res = p?.country?.code
assertNull(res)
4.1. let()メソッド
参照がnull許容でない値を保持している場合にのみアクションを実行するには、let演算子を使用できます。
値のリストがあり、そのリストにnull値もあるとします。
val firstName = "Tom"
val secondName = "Michael"
val names: List<String?> = listOf(firstName, null, secondName)
次に、 let 関数を使用して、namesリストのnull許容でないすべての要素に対してアクションを実行できます。
var res = listOf<String?>()
for (item in names) {
item?.let { res = res.plus(it) }
}
assertEquals(2, res.size)
assertTrue { res.contains(firstName) }
assertTrue { res.contains(secondName) }
4.2. also()メソッド
に追加の操作を適用する場合、たとえば、null許容でないすべての値にログオンする場合は、 also()メソッドを使用して、 let()でチェーンできます。
var res = listOf<String?>()
for (item in names) {
item?.let { res = res.plus(it); it }
?.also{it -> println("non nullable value: $it")}
}
nullではないすべての要素を出力します。
non nullable value: Tom
non nullable value: Michael
4.3. run()メソッド
Kotlinには、null許容参照に対して何らかの操作を実行するための run()メソッドがあります。 これはlet()と非常に似ていますが、関数本体の内部では、Run()メソッドが関数パラメーターの代わりにこの参照を操作します:
var res = listOf<String?>()
for (item in names) {
item?.run{res = res.plus(this)}
}
5. エルビス演算子
参照がある場合、参照が null を保持している場合、操作からデフォルト値を返したい場合があります。 これを実現するには、 elvis (?:)演算子を使用できます。 これは、JavaオプションクラスのorElse /orElseGetと同等です。
val value: String? = null
val res = value?.length ?: -1
assertEquals(res, -1)
value referenceがnull許容値を保持している場合、メソッドlengthが呼び出されます。
val value: String? = "name"
val res = value?.length ?: -1
assertEquals(res, 4)
6. Nullable Unsafe Get
Kotlinには、不在ロジックを明示的に処理せずにnull許容フィールドの値を取得するための安全でない演算子もありますが、慎重に使用する必要があります。
二重感嘆符演算子( !! )null許容参照から値を取得し、 NullPointerException それが成り立つなら
var b: String? = "value"
b = null
assertFailsWith<NullPointerException> {
b!!
}
null許容値がnull許容値ではない値を保持している場合、その値に対するアクションは正常に実行されます。
val b: String? = "value"
assertEquals(b!!.length, 5)
7. リストからのヌル値のフィルタリング
KotlinのListクラスには、null許容参照を保持するリストからnull許容でない値のみを返すユーティリティメソッド filterNotNull()があります。
val list: List<String?> = listOf("a", null, "b")
val res = list.filterNotNull()
assertEquals(res.size, 2)
assertTrue { res.contains("a") }
assertTrue { res.contains("b") }
これは、他の方法で自分で実装する必要があるロジックをカプセル化する非常に便利な構成です。
8. 結論
この記事では、Koltinのヌルセーフティ機能について詳しく説明しました。 null値を保持できる参照のタイプと保持できないタイプの参照を見ました。 「セーフコール」機能とelvis演算子を使用して、流暢なnull処理ロジックを実装しました。
これらすべての例とコードスニペットの実装は、 GitHubプロジェクトにあります。これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。