Kotlinの安全性を完全にするための総合ガイド

1概要

この記事では、Kotlin言語に組み込まれているnullセーフティ機能について説明します。 Kotlinは、null入力可能フィールドの包括的なネイティブ処理を提供します - 追加のライブラリは必要ありません。

2 Mavenの依存関係

始めるには、 pom.xmlに kotlin-stdlib__ Maven依存関係を追加する必要があります。

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
    <version>1.1.1</version>
</dependency>

最新版はhttps://search.maven.org/classic/#search%7C1%7Cg%3A%22org.jetbrains.kotlin%22%20AND%20a%3A%22kotlin-stdlib%22[]にあります。 Maven Central]。

3 NULL可能およびNULL不可の参照タイプ

  • Kotlinには、コンパイル時にプログラムの正当性に関する情報をプログラマに提供するためにコンパイラによって解釈される2種類の参照** があります。

  • デフォルトでは、Kotlinは値を null にすることはできないと仮定します。

var a: String = "value"

assertEquals(a.length, 5)

n をリファレンス a に代入することはできません。それを試みると、コンパイラエラーが発生します。

  • null可能な参照を作成したい場合は、型定義に疑問符(?)を追加する必要があります。

var b: String? = "value"

その後、 null を代入することができます。

b = null
  • b 参照にアクセスするときは、** Kotlinがこの変数に null を格納できることを知っているので、コンパイルエラーを回避するために 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 を保持している場合、safe callsの構文は 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() メソッドは関数パラメータの代わりにthis__参照を操作します。

var res = listOf<String?>()
for (item in names) {
    item?.run{res = res.plus(this)}
}

5エルビスオペレータ

ときには、参照があるときに、その参照に null が含まれている場合は、操作からデフォルト値を返したいことがあります。それを実現するために、 elvis ?: )演算子を使用できます。これは、Javaの Optional クラスの 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. NULL可能安全でない入手

Kotlinには、不在ロジックを明示的に処理せずにNULL可能フィールドの値を取得するための安全でない演算子もありますが、非常に慎重に使用する必要があります。

二重感嘆符演算子( !! )は、null許容参照から値を取り、 null. を保持している場合は NullPointerException をスローします。これは、 Optional.get() 操作と同等です。

var b: String? = "value"
b = null

assertFailsWith<NullPointerException> {
    b!!.length
}

NULL可能な参照がNULL可能でない値を保持している場合、その値に対するアクションは正常に実行されます。

val b: String? = "value"

assertEquals(b!!.length, 5)

7. リストからのNULL値のフィルタリング

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安全機能について詳しく説明しました。 null 値を保持できる型と保持できない型がありました。 「安全な呼び出し」機能と elvis 演算子を使用して、流暢な null 処理ロジックを実装しました。

これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/core-kotlin[GitHubプロジェクト]にあります。そのままインポートして実行します。