Unterscheiden Sie die Erweiterungsfunktionen in Kotlin

David Mbochi Njonge 21 Juni 2022
  1. Erstellen Sie eine Erweiterungsfunktion in Kotlin
  2. Verwenden Sie Lambda-Funktionen mit Erweiterungsfunktionen in Kotlin
  3. Verwenden Sie die Erweiterungsfunktion let() in Kotlin
  4. Verwenden Sie die Erweiterungsfunktion also() in Kotlin
  5. Verwenden Sie die Erweiterungsfunktion apply() in Kotlin
  6. Verwenden Sie die Erweiterungsfunktion takeIf() in Kotlin
  7. Verwenden Sie die Erweiterungsfunktion takeUnless() in Kotlin
  8. Fazit
Unterscheiden Sie die Erweiterungsfunktionen in Kotlin

In der objektorientierten Programmierung haben wir die Konzepte der Vererbung, Kapselung, Abstraktion und Polymorphie gelernt, aber diese reichen nicht aus, um unsere Anwendung flexibel, wiederverwendbar und wartbar zu strukturieren.

Entwurfsmuster kamen mit Hilfe von Entwurfsprinzipien und OOP-Konzepten zu Hilfe, um Lösungen für allgemeine Entwurfsprobleme einzuführen. Ein Designmuster, das dem, was wir in diesem Tutorial behandeln werden, sehr ähnlich ist, ist das Decorator-Designmuster.

Mit dem decorator-Entwurfsmuster können wir unserer Anwendung Funktionalität hinzufügen, ohne von einer anderen Klasse ausgehen zu müssen. In Kotlin können wir die gleichen funktionalen Designmuster erreichen, indem wir Kotlin-Erweiterungsfunktionen verwenden.

Erweiterungsfunktionen in Kotlin fügen einer Klasse Funktionalität hinzu, ohne von einer anderen Klasse zu erweitern oder das Decorator-Entwurfsmuster zu verwenden. Hinter den Kulissen können Erweiterungsfunktionen generisch sein und Lambda-Funktionen verwenden, um die von uns erwähnte Funktionalität zu realisieren.

In diesem Tutorial lernen wir, tief in jede der Erweiterungsfunktionen einzutauchen und geben für jede ein Beispiel. Zu den in diesem Artikel behandelten Erweiterungsfunktionen gehören: apply(), also(), let(), takeIf() und takeUnless().

Erstellen Sie eine Erweiterungsfunktion in Kotlin

Um eine Erweiterungsfunktion zu erstellen, definieren Sie den Typ, zu dem die Funktionalität hinzugefügt werden soll, z. B. String, Number oder eine Klasse, und verwenden Sie den Punktoperator, um die Methode zu definieren, an die die Funktionalität delegiert wird. Definieren Sie den Rückgabetyp der Erweiterungsfunktion und implementieren Sie schließlich die Logik der Methode in derselben Zeile.

Gehen Sie zum Intellij-Code-Editor und erstellen Sie ein neues Projekt mit dem Namen extension-exercise. Erstellen Sie unter src die Ordnerstruktur com.extension.

Erstellen Sie eine Main.kt-Datei im Ordner extension und fügen Sie den folgenden Code ein.

package com.extension

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

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

Im obigen Code haben wir eine Erweiterungsfunktion namens isGreaterThanTen() für den Typ Zahl definiert, die prüft, ob eine Zahl größer als 10 ist, und einen booleschen Wert zurückgibt.

Wenn Sie ab diesem Punkt eine beliebige Variable vom Typ Zahl aufrufen, haben Sie Zugriff auf die Methode isGreaterThanTen(), wie in der Hauptmethode oben gezeigt.

Beachten Sie, dass der boolesche Wert true in der Konsole protokolliert wird, wenn Sie das obige Programm ausführen.

true

Verwenden Sie Lambda-Funktionen mit Erweiterungsfunktionen in Kotlin

Hinter den Kulissen kann eine Lambda-Funktion als Schnittstelle definiert werden, die nur eine Methode enthält. Die Lambda-Funktion wird ohne Angabe des Funktionsnamens anonym an eine konkrete Funktion übergeben und der Rückgabetyp dann über das Pfeilsymbol definiert.

Erstellen Sie eine weitere Datei und verschieben Sie den vorherigen Code in die Datei. Kopieren Sie das folgende Beispiel und fügen Sie es in die leere Datei Main.kt ein.

package com.extension

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

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

}

Im obigen Code haben wir eine Erweiterungsfunktion namens isGreaterThanTen() definiert, die eine Lambda-Funktion als Parameter akzeptiert und einen booleschen Wert zurückgibt.

Die Lambda-Funktion, die wir block genannt haben, akzeptiert einen Parameter vom Typ Zahl und gibt einen booleschen Wert zurück. Dieser von der Lambda-Funktion zurückgegebene boolesche Wert wird an die Erweiterungsfunktion delegiert.

Im Vergleich zum vorherigen Beispiel definieren wir die Logik der Erweiterungsfunktion, nachdem wir isGreaterThanTen() für eine beliebige Variable vom Typ Zahl innerhalb der Hauptfunktion aufgerufen haben.

Führen Sie den obigen Code aus und beobachten Sie, dass wir dasselbe Ergebnis wie im vorherigen Beispiel haben. Die Ausgabe ist wie unten gezeigt.

true

Verwenden Sie die Erweiterungsfunktion let() in Kotlin

Verschieben Sie den vorherigen Code in die neue Datei, die wir erstellt haben, und fügen Sie den folgenden Code in die Datei Main.kt ein.

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

Die Funktion let() ist mit Generika definiert, d. h. sie kann jeden Typ verwenden. Das Objekt, das die Funktion let() aufruft, wird als Parameter der Lambda-Funktion übergeben.

Die Lambda-Funktion ist innerhalb der let()-Funktion definiert und gibt ein anderes Objekt als das als Parameter übergebene zurück.

Da der von der let()-Funktion zurückgegebene Wert derselbe ist wie der von der Lambda-Funktion zurückgegebene, haben wir den Rückgabewert der Lambda-Funktion an die let()-Funktion delegiert.

In der Hauptmethode haben wir eine Variable vom Typ Zahl definiert und unsere Erweiterungsfunktion aufgerufen, um eine Zeichenfolgendarstellung der Zahl zurückzugeben.

Anschließend haben wir den zurückgegebenen Wert und seinen Typ in der Konsole protokolliert, um zu überprüfen, ob die Erweiterungsfunktion wie erforderlich funktioniert. Beachten Sie, dass der an die Erweiterungsfunktion übergebene Typ eine Zahl war, der zurückgegebene Wert jedoch ein String war, wie unten gezeigt.

10
java.lang.String

Verwenden Sie die Erweiterungsfunktion also() in Kotlin

Verschieben Sie den vorherigen Code in die neue Datei, die wir erstellt haben, und fügen Sie den folgenden Code in die leere Datei Main.kt ein.

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

Das Objekt, das die Erweiterungsfunktion also() aufruft, wird als Parameter der Lambda-Funktion übergeben. Die Lambda-Funktion ist als Argument der Erweiterungsfunktion definiert und gibt keinen Wert zurück, der normalerweise mit einer Einheit bezeichnet wird.

Die Funktion also() gibt die aktuell verwendete Variable zurück, die zur weiteren Berechnung an die Lambda-Funktion delegiert wird. In der Hauptfunktion haben wir eine Variable vom Typ Zahl definiert, die an die Lambda-Funktion delegiert wird, um zu prüfen, ob der Wert gleich 10 ist.

Führen Sie den Code aus und beachten Sie, dass er einen wahren Wert zurückgibt, wie unten gezeigt.

true

Verwenden Sie die Erweiterungsfunktion apply() in Kotlin

Verschieben Sie den vorherigen Code in die neue Datei, die wir erstellt haben, und fügen Sie den folgenden Code in die leere Datei Main.kt ein.

package com.extension

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

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

Das Objekt, das die Erweiterungsfunktion apply() aufruft, wird als Methodenaufruf dieses Objekts an den Parameter der Lambda-Funktion übergeben. Die Lambda-Funktion hat keinen Rückgabewert.

Die Definition bedeutet, dass wir kein Objekt eines Typs verwenden müssen, um eine Methode aufzurufen, da die Lambda-Funktion die Funktionalität übernimmt. In diesem Fall müssen wir nur die benötigte Methode von einem Typ aufrufen.

In der Hauptfunktion haben wir eine Variable vom Typ Zahl definiert und mit der Methode apply() haben wir die Zahl in ein Double umgewandelt, indem wir die Methode toDouble() aufgerufen haben. Beachten Sie, dass keine Referenz auf ein Objekt verwendet wurde, um die Methode toDouble() aufzurufen.

Führen Sie den obigen Code aus und beachten Sie, dass der in der Konsole protokollierte Wert Double ist, wie unten gezeigt.

10.0

Verwenden Sie die Erweiterungsfunktion takeIf() in Kotlin

Verschieben Sie den vorherigen Code in die neue Datei, die wir erstellt haben, und fügen Sie den folgenden Code in die leere Datei Main.kt ein.

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

Das Objekt, das die Erweiterungsfunktion takeIf() aufruft, wird als Parameter der Lambda-Funktion übergeben. Die Lambda-Funktion wird als Argument dieser Methode übergeben und gibt einen booleschen Wert zurück.

Die Erweiterungsfunktion gibt das aufrufende Objekt nur zurück, wenn die Bedingung des Lambda-Ausdrucks als wahr ausgewertet wird. Andernfalls gibt es einen null-Wert zurück.

In der Hauptfunktion haben wir einen Wert vom Typ Zahl definiert, der mit takeIf() bestimmt, ob diese Zahl plus 10 kleiner als dreißig ist. Wenn die Bedingung wahr ist, wird der Wert 10 zurückgegeben; andernfalls wird ein null-Wert zurückgegeben.

Führen Sie den obigen Code aus und beachten Sie, dass der Lambda-Ausdruck als wahr ausgewertet wird und der Wert 10 zurückgegeben wird, wie unten gezeigt.

10

Verwenden Sie die Erweiterungsfunktion takeUnless() in Kotlin

Verschieben Sie den vorherigen Code in die neue Datei, die wir erstellt haben, und kopieren Sie den folgenden Code und fügen Sie ihn in die leere Datei Main.kt ein.

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

Das Objekt, das die Erweiterungsfunktion takeUnless() aufruft, wird als Parameter der Lambda-Funktion übergeben. Die Lambda-Funktion wird in dieser Methode definiert und gibt einen booleschen Wert zurück.

Der Unterschied zwischen takeIf() und takeUnless() besteht darin, dass dieses Beispiel nur dann einen Wert zurückgibt, wenn der Lambda-Ausdruck als false ausgewertet wird. Das bedeutet, dass der von der Erweiterungsfunktion zurückgegebene Wert die Umkehrung der booleschen Funktion ist, die von der Lambda-Funktion zurückgegeben wird.

Innerhalb der main-Methode haben wir das gleiche Beispiel wie oben definiert, aber beachten Sie, dass dieses Beispiel null zurückgibt, weil die Lambda-Funktion zu true ausgewertet wird, was zu false invertiert wird.

null

Fazit

In diesem Tutorial haben wir gelernt, wie man Funktionen in Kotlin mithilfe der Erweiterungsfunktionen hinzufügt. Zu den behandelten Erweiterungsfunktionen gehören: Verwendung von let(), also(), apply(), takeIf() und takeUnless().

Beachten Sie, dass diese Erweiterungsfunktionen bereits in der Kotlin-API definiert sind und Sie sie nicht wie in diesem Tutorial definieren müssen.

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