web-dev-qa-db-ja.com

Kotlinの違いも、Kotlinのapply、let、use、takeIf、およびtakeUnless

これらのアイテムに関する多くのKotlinドキュメントを読みました。しかし、私はそれほどはっきりと理解できません。

Kotlin letalsotakeIfおよびtakeUnlessの詳細は何ですか?

各アイテムの例が必要です。 Kotlinのドキュメントを投稿しないでください。リアルタイムの例とこれらのアイテムのユースケースが必要です。

19
Bhuvanesh BS

させる

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...
}
_

takeIf

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!")
_

助けて

  • https://try.kotlinlang.org/ を使用して、簡単にテストできます。例があります こちら
  • 標準ライブラリ here のソースをチェックアウトできます。 letalsotakeIfおよびtakeUnlessここ
36
Kevin Robatel

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()) }

上記の例では、numberphoneNumberの文字列のみを持ち、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になります。

11
Bhuvanesh BS