J'essaie de comprendre pourquoi let est nécessaire. Dans l'exemple ci-dessous, j'ai une classe Test avec une fonction giveMeFive:

public class Test() {
    fun giveMeFive(): Int {
        return 5
    }
}

Étant donné le code suivant:

var test: Test? = Test()

var x: Int? = test?.giveMeFive()

test = null

x = test?.giveMeFive()
x = test?.let {it.giveMeFive()}

X est défini sur 5, puis après que le test est défini sur null, l'appel de l'une des instructions suivantes renvoie null pour x. Étant donné que l'appel d'une méthode sur une référence null ignore l'appel et définit x sur null, pourquoi aurais-je besoin d'utiliser let? Y a-t-il des cas où juste?. ne fonctionnera pas et laissez est nécessaire?

De plus, si la fonction appelée ne renvoie rien, alors?. va sauter l'appel et je n'ai pas besoin? .let là non plus.

0
user982687 26 janv. 2019 à 23:56

3 réponses

Meilleure réponse

let ()

fun <T, R> T.let(f: (T) -> R): R = f(this)

Let () est une fonction de portée: utilisez-la chaque fois que vous voulez définir une variable pour une portée spécifique de votre code mais pas au-delà. Il est extrêmement utile de garder votre code bien autonome afin de ne pas avoir de variables "qui s'échappent": être accessible au-delà du point où elles devraient être.

DbConnection.getConnection().let { connection ->
}

// la connexion n'est plus visible ici

Let () peut également être utilisé comme alternative au test avec null:

val map : Map<String, Config> = ...
val config = map[key]
// config is a "Config?"
config?.let {
// This whole block will not be executed if "config" is null.
// Additionally, "it" has now been cast to a "Config" (no 
question mark)
}

A simple go to chart when to use when.

5
Sharan 26 janv. 2019 à 21:09

Vous devez utiliser let si vous voulez enchaîner des appels de fonction qui ne sont pas définis sur le type à partir duquel vous chaînez.

Disons que la définition de votre fonction était plutôt la suivante:

// Not defined inside the Test class
fun giveMeFive(t: Test) {
    return 5
}

Maintenant, si vous avez un nullable Test et que vous voulez appeler cette fonction dans une chaîne, vous devez utiliser let:

val x = test?.let { giveMeFive(it) }
2
marstran 26 janv. 2019 à 21:02

La fonction d'extension .let {} dans Kotlin:

  1. Prend la référence d'objet comme paramètre sur lequel .let{} est appelé.

  2. Renvoie la valeur de tout type de données non primitif qui a été renvoyé avec la fonction let{}. Par défaut, il renvoie la valeur undefined de la classe kotlin.Any.

Déclaration dans le package kotlin:

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

Démonstration pratique simple pour voir comment la fonction d'extension .let{} fonctionne dans Kotlin.

Exemple de code 1: -

val builder = StringBuilder("Hello ")
println("Print 0: $builder")

val returnVal = builder.let { arg ->
    arg.append("World")
    println("Print 1: $arg")

    "Done" // Returnning some string
}
println("Print 2: $builder")
println("Print 3: $returnVal")

Exemple de sortie de code 1: -

Print 0: Hello 
Print 1: Hello World
Print 2: Hello World
Print 3: Done

Dans l'exemple de code 1:

  1. Nous avons créé l'objet final de type StringBuilder avec la valeur d'initialisation "Hello".

  2. Dans builder.let{}, la référence de l'objet du générateur sera transmise à arg.

  3. Ici, la sortie Print 2: Hello World et Print 3: Hello World signifie que builder et arg, tous deux pointent vers le même StringBuilder object-reference. C'est pourquoi ils impriment tous les deux la même valeur String.

  4. Dans la dernière ligne du bloc fonctionnel .let{}, nous renvoyons la valeur "Done" String qui sera attribuée à returnVal.

* Par conséquent, nous obtenons la sortie Print 3: Done de returnVal.

Exemple de code 2: -

val builder = StringBuilder("Hello ")
println("Print 0: $builder")
val returnVal = builder.let { arg ->
    arg.append("World")
    println("Print 1: $arg")
    arg.length
    }

println("Print 2: $builder")
println("Print 3: $returnVal") // Now return val is int = length of string.

Exemple de sortie de code 2: -

Print 0: Hello 
Print 1: Hello World
Print 2: Hello World
Print 3: 11

Dans l'exemple de code 2:

Quelle est la différence:

Dans la dernière ligne du bloc fonctionnel .let{}, nous renvoyons la valeur Int égale à la longueur de l'objet StringBuilder arg dont la valeur sur cette ligne de code est "Hello World". Ainsi, length = 11 de type Int sera attribué à returnVal .

* Par conséquent, nous obtenons Print 3: 11 comme sortie de returnVal.

Essayez également ceux-ci: -

  • .courir() {}
  • .appliquer() {}
  • avec (obj) {}
  • .aussi() {}

Bon codage ...

0
Rahul Raina 12 avril 2020 à 04:03