web-dev-qa-db-fra.com

différence entre kotlin aussi, appliquer, laisser, utiliser, takeIf et takeUnless dans Kotlin

J'ai lu de nombreux documents Kotlin sur ces articles. Mais je ne peux pas comprendre aussi clairement.

À quoi sert Kotlin let, aussi, takeIf et takeUnless en détail?

J'ai besoin d'un exemple de chaque article. Veuillez ne pas publier la documentation de Kotlin. J'ai besoin d'un exemple en temps réel et des cas d'utilisation de ces éléments.

19
Bhuvanesh BS

laisser

public inline fun <T, R> T.let(block: (T) -> R): R = block(this)

Prenez le récepteur et passez-le à une fonction passée en paramètre. Renvoie le résultat de la fonction.

val myVar = "hello!"
myVar.let { println(it) } // Output "hello!"

Vous pouvez utiliser let pour un contrôle de sécurité nul:

val myVar = if (Random().nextBoolean()) "hello!" else null
myVar?.let { println(it) } // Output "hello!" only if myVar is not null

aussi

public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }

Exécutez la fonction passée avec le récepteur comme paramètre et retournez le récepteur .
C'est comme laisser mais toujours retourner le récepteur , pas le résultat de la fonction.

Vous pouvez l'utiliser pour faire quelque chose sur un objet.

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

Retourne le récepteur si la fonction (prédicat) renvoie true, sinon retourne null.

println(myVar.takeIf { it is Person } ?: "Not a person!")

à moins

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null

Identique à takeIf, mais avec prédicat inversé. Si vrai, retournez null, sinon retournez le récepteur .

println(myVar.takeUnless { it is Person } ?: "It's a person!")

Aidez-moi

  • Vous pouvez utiliser https://try.kotlinlang.org/ pour tester facilement. Vous pouvez trouver des exemples ici .
  • Vous pouvez vérifier la source de la lib standard ici . let, also, takeIf et takeUnlessici .
36
Kevin Robatel

let, also, apply, takeIf, takeUnless sont des fonctions d'extension dans Kotlin.

Pour comprendre ces fonctions, vous devez comprendre fonctions d'extension et fonctions Lambda dans Kotlin.

Fonction d'extension:

En utilisant la fonction d'extension, nous pouvons créer une fonction pour une classe sans hériter d'une classe.

Kotlin, similaire à C # et Gosu, offre la possibilité d'étendre une classe avec de nouvelles fonctionnalités sans avoir à hériter de la classe ou utiliser n'importe quel type de modèle de conception tel que Decorator. Cela se fait via des déclarations spéciales appelées extensions. Kotlin prend en charge les fonctions d'extension et les propriétés d'extension.

Ainsi, pour rechercher uniquement des nombres dans String, vous pouvez créer une méthode comme ci-dessous sans hériter de la classe String.

fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())

vous pouvez utiliser ce qui précède fonction d'extension comme ceci,

val phoneNumber = "8899665544"
println(phoneNumber.isNumber)

qui imprime true.

Fonctions Lambda:

Les fonctions Lambda sont exactement comme Interface en Java. Mais dans Kotlin, les fonctions lambda peuvent être passées comme paramètre dans les fonctions.

Exemple:

fun String.isNumber(block: () -> Unit): Boolean {
    return if (this.matches("[0-9]+".toRegex())) {
        block()
        true
    } else false
}

Vous voyez, le bloc est une fonction lambda et il est passé en paramètre. Vous pouvez utiliser la fonction ci-dessus comme ceci,

val phoneNumber = "8899665544"
    println(phoneNumber.isNumber {
        println("Block executed")
    })

La fonction ci-dessus s'imprimera comme ceci,

Block executed
true

J'espère que vous avez maintenant une idée des fonctions d'extension et des fonctions Lambda. Maintenant, nous pouvons accéder aux fonctions d'extension une par une.

let

public inline fun <T, R> T.let(block: (T) -> R): R = block(this)

Deux types T et R utilisés dans la fonction ci-dessus.

T.let

T pourrait être n'importe quel objet comme la classe String. vous pouvez donc invoquer cette fonction avec n'importe quel objet.

block: (T) -> R

En paramètre de let, vous pouvez voir la fonction lambda ci-dessus. En outre, l'objet appelant est passé en tant que paramètre de la fonction. Vous pouvez donc utiliser l'objet de classe appelant à l'intérieur de la fonction. puis il retourne le R (un autre objet).

Exemple:

val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }

Dans l'exemple ci-dessus, prenons String comme paramètre de sa fonction lambda et il retourne Pair en retour.

De la même manière, d'autres fonctions d'extension fonctionnent.

aussi

public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }

la fonction d'extension also prend la classe appelante comme paramètre de fonction lambda et ne renvoie rien.

Exemple:

val phoneNumber = "8899665544"
phoneNumber.also { number ->
    println(number.contains("8"))
    println(number.length)
 }

appliquer

public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }

Identique à également mais le même objet appelant passé en tant que fonction afin que vous puissiez utiliser les fonctions et autres propriétés sans l'appeler ni le nom du paramètre.

Exemple:

val phoneNumber = "8899665544"
phoneNumber.apply { 
    println(contains("8"))
    println(length)
 }

Vous pouvez voir dans l'exemple ci-dessus les fonctions de la classe String directement invoquées dans la fonction lambda.

takeIf

public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null

Exemple:

val phoneNumber = "8899665544"
val number = phoneNumber.takeIf { it.matches("[0-9]+".toRegex()) }

Dans l'exemple ci-dessus, number aura une chaîne de phoneNumber seulement elle correspond à regex. Sinon, ce sera null.

takeUnless

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null

C'est l'inverse de takeIf.

Exemple:

val phoneNumber = "8899665544"
val number = phoneNumber.takeUnless { it.matches("[0-9]+".toRegex()) }

number aura une chaîne de phoneNumber uniquement si elle ne correspond pas à regex. Sinon, ce sera null.

11
Bhuvanesh BS