Différencier les fonctions d'extension dans Kotlin

David Mbochi Njonge 30 janvier 2023
  1. Créer une fonction d’extension dans Kotlin
  2. Utiliser les fonctions Lambda avec les fonctions d’extension dans Kotlin
  3. Utiliser la fonction d’extension let() dans Kotlin
  4. Utiliser la fonction d’extension also() en Kotlin
  5. Utiliser la fonction d’extension apply() dans Kotlin
  6. Utiliser la fonction d’extension takeIf() dans Kotlin
  7. Utiliser la fonction d’extension takeUnless() dans Kotlin
  8. Conclusion
Différencier les fonctions d'extension dans Kotlin

En programmation orientée objet, nous avons appris les concepts d’héritage, d’encapsulation, d’abstraction et de polymorphisme, mais ceux-ci ne suffisent pas à structurer notre application de manière flexible, réutilisable et maintenable.

Les modèles de conception, avec l’aide des principes de conception et des concepts OOP, sont venus à la rescousse pour introduire des solutions aux problèmes de conception courants. Un modèle de conception très similaire à ce que nous allons couvrir dans ce didacticiel est le modèle de conception du décorateur.

Le modèle de conception de décorateur nous permet d’ajouter des fonctionnalités à notre application sans s’étendre à partir d’une autre classe. Dans Kotlin, nous pouvons obtenir les mêmes modèles de conception de fonctionnalités en utilisant les fonctions d’extension Kotlin.

Les fonctions d’extension dans Kotlin ajoutent des fonctionnalités à une classe sans s’étendre à partir d’une autre classe ni utiliser le modèle de conception du décorateur. Dans les coulisses, les fonctions d’extension peuvent être génériques et peuvent utiliser des fonctions lambda pour réaliser la fonctionnalité que nous avons mentionnée.

Dans ce didacticiel, nous allons apprendre à approfondir chacune des fonctions d’extension et donner un exemple pour chacune. Les fonctions d’extension couvertes dans cet article incluent : apply(), also(), let(), takeIf() et takeUnless().

Créer une fonction d’extension dans Kotlin

Pour créer une fonction d’extension, définissez le type auquel vous souhaitez ajouter la fonctionnalité, tel que String, Number ou une classe, et utilisez l’opérateur point pour définir la méthode déléguée de la fonctionnalité. Définissez le type de retour de la fonction d’extension et enfin implémentez la logique de la méthode sur la même ligne.

Accédez à l’éditeur de code Intellij et créez un nouveau projet nommé extension-exercise. Sous le src, créez la structure de dossiers com.extension.

Créez un fichier Main.kt sous le dossier extension et collez le code suivant.

package com.extension

fun Number.isGreaterThanTen(): Boolean = this.toInt() > 10;

fun main() {
    val  num = 100;
    println(num.isGreaterThanTen());
}

Dans le code ci-dessus, nous avons défini une fonction d’extension nommée isGreaterThanTen() sur le type Number qui vérifie si un nombre est supérieur à 10 et renvoie une valeur booléenne.

Si vous invoquez une variable de type numéro à partir de ce point, vous aurez accès à la méthode isGreaterThanTen(), comme indiqué dans la méthode principale ci-dessus.

Notez qu’une valeur booléenne de true est enregistrée dans la console lorsque vous exécutez le programme ci-dessus.

true

Utiliser les fonctions Lambda avec les fonctions d’extension dans Kotlin

Dans les coulisses, une fonction lambda peut être définie comme une interface qui ne contient qu’une seule méthode. La fonction lambda est transmise de manière anonyme à une fonction concrète sans spécifier le nom de la fonction, et le type de retour est ensuite défini à l’aide du symbole de flèche.

Créez un autre fichier et déplacez le code précédent dans le fichier. Copiez et collez l’exemple suivant dans le fichier vide Main.kt.

package com.extension

fun Number.isGreaterThanTen(block: (Number) -> Boolean): Boolean = block(this);

fun main() {
    val num = 100;
    println(num.isGreaterThanTen { number ->
        number.toInt() > 10
    })

}

Dans le code ci-dessus, nous avons défini une fonction d’extension nommée isGreaterThanTen() qui accepte une fonction lambda en tant que paramètre et renvoie un booléen.

La fonction lambda, que nous avons nommée block, accepte un paramètre de type Number et renvoie une valeur booléenne. Cette valeur booléenne renvoyée par la fonction lambda est déléguée à la fonction d’extension.

Par rapport à l’exemple précédent, nous définissons la logique de la fonction d’extension après avoir invoqué le isGreaterThanTen() sur toute variable de type Number à l’intérieur de la fonction principale.

Exécutez le code ci-dessus et observez que nous avons le même résultat que l’exemple précédent. La sortie est comme indiqué ci-dessous.

true

Utiliser la fonction d’extension let() dans Kotlin

Déplacez le code précédent vers le nouveau fichier que nous avons créé et collez le code suivant dans le fichier Main.kt.

package com.extension

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

fun  main(){
    val num = 10;
    val result = num.let { number -> number.toString() }
    println(result);
    println(result::class.java.typeName);
}

La fonction let() est définie à l’aide de génériques, ce qui signifie qu’elle peut utiliser n’importe quel type. L’objet invoquant la fonction let() est passé en paramètre de la fonction lambda.

La fonction lambda est définie à l’intérieur de la fonction let() et renvoie un objet différent de celui passé en paramètre.

Comme la valeur retournée par la fonction let() est la même que la fonction retournée par la fonction lambda, nous avons délégué la valeur de retour de la fonction lambda à la fonction let().

Dans la méthode principale, nous avons défini une variable de type Number et appelé notre fonction d’extension pour renvoyer une représentation sous forme de chaîne du nombre.

Nous avons ensuite enregistré la valeur renvoyée et son type dans la console pour vérifier que la fonction d’extension fonctionne comme requis. Notez que le type passé à la fonction d’extension était un nombre, mais que la valeur renvoyée était une chaîne, comme indiqué ci-dessous.

10
java.lang.String

Utiliser la fonction d’extension also() en Kotlin

Déplacez le code précédent vers le nouveau fichier que nous avons créé et collez le code suivant dans le fichier vide Main.kt.

package com.extension

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

fun main(){
    val  num = 10;
    num.also {i ->
        println(i == 10)
    }
}

L’objet invoquant la fonction d’extension also() est passé en paramètre de la fonction lambda. La fonction lambda est définie comme l’argument de la fonction d’extension et ne renvoie aucune valeur habituellement désignée par une Unité.

La fonction also() renvoie la variable actuelle que vous utilisez, qui est déléguée à la fonction lambda pour un calcul ultérieur. Dans la fonction main, nous avons défini une variable de type Number déléguée à la fonction lambda pour vérifier si la valeur vaut 10.

Exécutez le code et notez qu’il renvoie une valeur vraie, comme indiqué ci-dessous.

true

Utiliser la fonction d’extension apply() dans Kotlin

Déplacez le code précédent dans le nouveau fichier que nous avons créé et collez le code suivant dans le fichier vide Main.kt.

package com.extension

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

fun main(){
    val num = 10;
    num.apply {
        println(toDouble());
    }
}

L’objet invoquant la fonction d’extension apply() est passé en tant qu’invocation de méthode de cet objet au paramètre de la fonction lambda. La fonction lambda n’a pas de valeur de retour.

La définition signifie que nous n’avons pas besoin d’utiliser un objet d’un type pour appeler une méthode car la fonction lambda gère la fonctionnalité. Dans ce cas, nous n’avons qu’à appeler la méthode dont nous avons besoin à partir d’un type.

Dans la fonction principale, nous avons défini une variable de type Number, et à l’aide de la méthode apply(), nous avons converti le Number en Double en appelant la méthode toDouble(). Notez qu’aucune référence à un objet n’a été utilisée pour appeler la méthode toDouble().

Exécutez le code ci-dessus et notez que la valeur enregistrée dans la console est Double, comme indiqué ci-dessous.

10.0

Utiliser la fonction d’extension takeIf() dans Kotlin

Déplacez le code précédent vers le nouveau fichier que nous avons créé et collez le code suivant dans le fichier vide Main.kt.

package com.extension

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

fun main() {
    val  num = 10;
    println(num.takeIf { i ->
        i.plus(10) < 30
    })
}

L’objet invoquant la fonction d’extension takeIf() est passé en paramètre de la fonction lambda. La fonction lambda est passée comme argument de cette méthode et renvoie une valeur booléenne.

La fonction d’extension renvoie l’objet appelant uniquement lorsque la condition de l’expression lambda est évaluée à true. Sinon, il renvoie une valeur null.

Dans la fonction main, nous avons défini une valeur de type Number qui utilise le takeIf() pour déterminer si ce nombre plus 10 est inférieur à trente. Si la condition est vraie, la valeur 10 est renvoyée ; sinon, une valeur null est retournée.

Exécutez le code ci-dessus et notez que l’expression lambda est évaluée à true et que la valeur 10 est renvoyée, comme indiqué ci-dessous.

10

Utiliser la fonction d’extension takeUnless() dans Kotlin

Déplacez le code précédent dans le nouveau fichier que nous avons créé et copiez et collez le code suivant dans le fichier vide Main.kt.

package com.extension

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

fun main() {
    val num = 10;
    println(num.takeUnless { i ->
        i.plus(10) < 30
    })
}

L’objet invoquant la fonction d’extension takeUnless() est passé en paramètre de la fonction lambda. La fonction lambda est définie dans cette méthode et renvoie une valeur booléenne.

La différence entre takeIf() et takeUnless() est que cet exemple ne renvoie une valeur que lorsque l’expression lambda est évaluée à false. Cela signifie que la valeur renvoyée par la fonction d’extension est l’inverse de la fonction booléenne renvoyée par la fonction lambda.

Dans la méthode principale, nous avons défini le même exemple que ci-dessus, mais notez que cet exemple renverra null car la fonction lambda est évaluée à true, qui est inversée en false.

null

Conclusion

Ce didacticiel nous a appris à ajouter des fonctionnalités dans Kotlin à l’aide des fonctions d’extension. Les fonctions d’extension couvertes incluent : l’utilisation de let(), also(), apply(), takeIf() et takeUnless().

Notez que ces fonctions d’extension sont déjà définies dans l’API Kotlin, et vous n’avez pas à les définir comme nous l’avons fait dans ce tutoriel.

David Mbochi Njonge avatar David Mbochi Njonge avatar

David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.

LinkedIn GitHub