これらのアイテムに関する多くのKotlinドキュメントを読みました。しかし、私はそれほどはっきりと理解できません。
Kotlin let、also、takeIfおよびtakeUnlessの詳細は何ですか?
各アイテムの例が必要です。 Kotlinのドキュメントを投稿しないでください。リアルタイムの例とこれらのアイテムのユースケースが必要です。
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
receiverを受け取り、パラメーターとして渡された関数に渡します。関数の結果を返します。
_val myVar = "hello!"
myVar.let { println(it) } // Output "hello!"
_
Null安全チェックにlet
を使用できます。
_val myVar = if (Random().nextBoolean()) "hello!" else null
myVar?.let { println(it) } // Output "hello!" only if myVar is not null
_
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
パラメーターとしてreceiverで渡された関数を実行し、receiverを返します。
letに似ていますが、関数の結果ではなく、常にreceiverを返します。
オブジェクトで何かをするために使用できます。
_val person = Person().also {
println("Person ${it.name} initialized!")
// Do what you want here...
}
_
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
関数(述語)がtrueを返す場合はreceiverを返し、そうでない場合はnullを返します。
_println(myVar.takeIf { it is Person } ?: "Not a person!")
_
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
takeIf
と同じですが、述語が逆になっています。 trueの場合はnullを返し、そうでない場合はreceiverを返します。
_println(myVar.takeUnless { it is Person } ?: "It's a person!")
_
let
、also
、takeIf
およびtakeUnless
ここ 。let、also、apply、takeIf、takeUnlessはKotlinの拡張機能です。
これらの機能を理解するには、Kotlinの拡張機能およびラムダ機能を理解する必要があります。
拡張機能:
拡張関数を使用することにより、クラスを継承せずにクラスの関数を作成できます。
Kotlinは、C#やGosuと同様に、クラスから継承したり、デコレーターなどのデザインパターンを使用したりすることなく、クラスを新しい機能で拡張する機能を提供します。これは、拡張と呼ばれる特別な宣言を介して行われます。 Kotlinは拡張機能と拡張プロパティをサポートしています。
したがって、String
に数字だけがあるかどうかを調べるには、String
クラスを継承せずに以下のようなメソッドを作成できます。
fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())
上記のように拡張関数を使用できます。
val phoneNumber = "8899665544"
println(phoneNumber.isNumber)
これはtrue
を出力します。
ラムダ関数:
Lambda関数は、Javaのインターフェイスに似ています。しかし、Kotlinでは、ラムダ関数を関数のパラメーターとして渡すことができます。
例:
fun String.isNumber(block: () -> Unit): Boolean {
return if (this.matches("[0-9]+".toRegex())) {
block()
true
} else false
}
ご覧のとおり、ブロックはラムダ関数であり、パラメーターとして渡されます。上記の関数を次のように使用できます。
val phoneNumber = "8899665544"
println(phoneNumber.isNumber {
println("Block executed")
})
上記の関数は次のように印刷されます。
Block executed
true
これで、Extension関数とLambda関数についてのアイデアを得たと思います。これで、拡張機能に1つずつアクセスできます。
let
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
上記の関数で使用される2つのタイプTおよびR。
T.let
T
には、Stringクラスのような任意のオブジェクトを指定できます。したがって、任意のオブジェクトでこの関数を呼び出すことができます。
block: (T) -> R
Letのパラメーターでは、上記のラムダ関数を見ることができます。また、呼び出しオブジェクトは、関数のパラメーターとして渡されます。そのため、関数内で呼び出しクラスオブジェクトを使用できます。その後、R
(別のオブジェクト)を返します。
例:
val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }
上記の例では、letはラムダ関数のパラメーターとしてStringを取り、Pairを返します。
同様に、他の拡張機能も機能します。
また
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
拡張関数also
は、呼び出しクラスをラムダ関数パラメーターとして受け取り、何も返しません。
例:
val phoneNumber = "8899665544"
phoneNumber.also { number ->
println(number.contains("8"))
println(number.length)
}
適用
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
これも同じですが、関数として渡された同じ呼び出しオブジェクトなので、関数やパラメーター名を呼び出さずに関数や他のプロパティを使用できます。
例:
val phoneNumber = "8899665544"
phoneNumber.apply {
println(contains("8"))
println(length)
}
上記の例では、ラムダ関数内で直接呼び出されるStringクラスの関数を見ることができます。
takeIf
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
例:
val phoneNumber = "8899665544"
val number = phoneNumber.takeIf { it.matches("[0-9]+".toRegex()) }
上記の例では、number
はphoneNumber
の文字列のみを持ち、regex
と一致します。それ以外の場合は、null
になります。
takeUnless
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
TakeIfの逆です。
例:
val phoneNumber = "8899665544"
val number = phoneNumber.takeUnless { it.matches("[0-9]+".toRegex()) }
number
は、phoneNumber
と一致しない場合にのみ、regex
の文字列を持ちます。それ以外の場合は、null
になります。