KotlinのNull安全性に関する包括的なガイド
1. 概要
この記事では、Kotlin言語に組み込まれているnullの安全機能について説明します。 Kotlinは、null許容フィールドの包括的なネイティブ処理を提供します。追加のライブラリは必要ありません。
2. メーベン依存
開始するには、kotlin-stdlib Maven依存関係をpom.xml:に追加する必要があります
org.jetbrains.kotlin
kotlin-stdlib
1.1.1
最新バージョンはMaven Centralにあります。
3. ヌル可能およびヌル不可能な参照型
コンパイル時にプログラムの正確性に関する情報をプログラマーに提供するためにコンパイラーによって解釈されるKotlin has two types of references-null許容のものとそうでないもの。
デフォルトでは、Kotlinは値をnullにすることはできないと想定しています。
var a: String = "value"
assertEquals(a.length, 5)
nullを参照aに割り当てることはできません。割り当てようとすると、コンパイラエラーが発生します。
If we want to create a nullable reference, we need to create append the question mark(?) to the type definition:
var b: String? = "value"
その後、nullを割り当てることができます。
b = null
Kotlinはこの変数がnullを保持できることを知っているため、コンパイルエラーを回避するためのWhen we want to access the b reference, we must handle the null case explicitly:
if (b != null) {
println(b.length)
} else {
assertNull(b)
}
4. 安全な通話
このような方法ですべてのNULL可能参照を処理するのは面倒です。 幸い、Kotlinには「安全な呼び出し」の構文があります。この構文により、プログラマーはexecute an action only when the specific reference holds a non-null valueを実行できます。
この機能を説明するために、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 = listOf(firstName, null, secondName)
次に、let関数を使用して、namesリストのnull許容でないすべての要素に対してアクションを実行できます。
var res = listOf()
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()メソッド
to apply some additional operation, for example logging on every non-nullable value we can use analso()メソッドが必要で、それをlet():でチェーンする場合
var res = listOf()
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()メソッド operates on this reference instead of a function parameter:
var res = listOf()
for (item in names) {
item?.run{res = res.plus(this)}
}
5. エルビス演算子
参照がある場合、参照がnullを保持していると、操作からデフォルト値を返したい場合があります。 これを実現するために、elvis(?:)演算子を使用できます。 これは、JavaOptionalクラスのorElse/orElseGetと同等です。
val value: String? = null
val res = value?.length ?: -1
assertEquals(res, -1)
value参照がnull許容値を保持している場合、メソッドlengthが呼び出されます。
val value: String? = "name"
val res = value?.length ?: -1
assertEquals(res, 4)
6. Nullable Unsafe Get
Kotlinには、不在ロジックを明示的に処理せずにnull許容フィールドの値を取得するための安全でない演算子もありますが、慎重に使用する必要があります。
二重感嘆符演算子(!!)は、NULL可能参照から値を取得し、null.を保持している場合はNullPointerExceptionをスローします。これはOptional.get()操作と同等です。
var b: String? = "value"
b = null
assertFailsWith {
b!!.length
}
NULL可能参照にNULL不可値が保持されている場合、その値に対するアクションは正常に実行されます。
val b: String? = "value"
assertEquals(b!!.length, 5)
7. リストからのNULL値のフィルタリング
KotlinのListクラスには、null許容参照を保持するリストからnull不可能な値のみを返すユーティリティメソッドfilterNotNull()があります。
val list: List = 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 projectにあります。これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。