Was bedeutet „.()“ in Kotlin?

Lesezeit: 4 Minuten

Benutzer-Avatar
Allan W

Ich habe Beispiele gesehen, bei denen eine Funktion ein Argument hat, das von ClassName.() angegeben wurde. Dies scheint keine Erweiterungsfunktion zu sein, sondern ClassName.Function()

Ein Beispiel ist Kottermesser:

private val View.viewFinder: View.(Int) -> View?
    get() = { findViewById(it) }

dessen Funktion ich nicht genau kenne,

und MaterialSchubladeKt

fun Activity.drawer(setup: DrawerBuilderKt.() -> Unit = {}): Drawer {
    val builder = DrawerBuilderKt(this)
    builder.setup()
    return builder.build()
}

Wo der Code es Ihnen ermöglicht, direkt anzurufen

drawer {
    ...
}

anstatt Argumente zu geben, die von Klammern umgeben sind.

Gibt es dazu irgendwo Unterlagen?

  • Sie sollten sich Lambdas mit Empfängern ansehen: kotlinlang.org/docs/reference/…

    – Lukas Lechner

    8. Juni 2017 um 6:00 Uhr

  • Und wenn der letzte Parameter einer Funktion ein Lambda ist, können Sie es aus der Klammer herausziehen und in einen von { } umgebenen Block ziehen, wie in Ihrem Beispiel drawer Beispiel

    – Lukas Lechner

    8. Juni 2017 um 6:02 Uhr

Benutzer-Avatar
LF00

Eine Funktion, die in Kotlin nichts aufnimmt und nichts zurückgibt, sieht so aus:

var function : () -> Unit

Der Unterschied besteht darin, dass die Funktion in Ihrem Code nichts aufnimmt, nichts zurückgibt, wird aber für ein Objekt aufgerufen.

Zum Beispiel,

class Builder (val multiplier: Int) {
    
    fun invokeStuff(action: (Builder.() -> Unit)) {
        this.action()
    }
    
    fun multiply(value: Int) : Int {
        return value * multiplier
    }
}

Das Wichtige hier ist die Art und Weise, wie wir den Typ deklariert haben action

action: (Builder.() -> Unit)

Dies ist eine Funktion, die nichts zurückgibt, nichts aber aufnimmt wird für ein Objekt des Typs aufgerufen Builder.

Das heißt, wenn wir diesen Builder so verwenden

var builder = Builder(10)
builder.invokeStuff({
    var result = multiply(1)
    println(result)
})

Der Kontext von this wurde auf das Builder-Objekt gesetzt und wir können im Builder deklarierte Funktionen aufrufen.

Weitere Informationen finden Sie hier.

das ist eine gute Frage. Also, wenn Sie diese Art von Aussage haben: T.()

Dies bedeutet, dass in dem Lambda, das Sie übergeben werden, “this” (das aktuelle Objekt) vom Typ T ist. Schauen wir uns an, wie einfach es zu verstehen ist:

Nehmen wir an, wir haben eine Klasse mit einer Funktion namens myFun, die ein wie folgt definiertes Lambda aufnimmt:

 class MyObject {
        fun myFun(doSomething: MyObject.()->Unit) {
            doSomething()
        }

        fun doAnotherThing() {
            Timber.d("myapp", "doing another thing")
        }
    }

Um diese Funktion aufzurufen, würde ich Folgendes tun:

MyObject().myFun { doAnotherThing() }

Sehen Sie, wie es wusste, die MyObject()-Referenz als “this” zu verwenden. das ruft wirklich this.doAnotherThing() auf, wobei dies die soeben erstellte Myobject()-Instanz ist.

hätte man auch machen können:

MyObject().apply{myFun { doAnotherThing() }}  

  • Hallo, warum rufst du es immer mit doAnotherThing() auf? wie hängt doAnotherThing() hier zusammen? Ich verstehe es nicht

    – jpganz18

    8. Oktober 2020 um 12:33 Uhr

  • Ich zeige nur, dass die Referenz this.doAnotherThing() nicht verwenden muss, einfach doAnotherThing()

    – j2emanue

    16. Oktober 2020 um 2:30 Uhr

Benutzer-Avatar
BollMose

Es gibt ein Missverständnis, dass T.() -> Y (T.()) -> Y ist, aber eigentlich T.(()->Y) ist. Wie wir wissen, ist (X)->Y ein Lambda, also ist T.(X)->Y eine Erweiterung von T.

Wenn es keinen Parameter gibt, ist die Form T.() -> Y

Es ist interessant, dass wir es auf zwei Arten als Blow bezeichnen können.

import kotlinx.coroutines.*


open class MyClass(var name: String){
    open fun something(){println("myclass something")}
}


fun main() = runBlocking{
    val me = MyClass("Boll")
    val someMethod: MyClass.(Int) -> String = { n ->
        List(n){"X"}.joinToString(separator="", postfix=":${this.name}")
    }
    val some = me.someMethod(10)
    //val some = someMethod(me, 10)
    println(some)

    val anotherMehtod: MyClass.() -> String = { 
        "Y:"+this.name
    }
    //val another = me.anotherMehtod()
    val another = anotherMehtod(me) 
    println(another)
}

  • Das ist wirklich interessant zu finden. Ich bin ziemlich neugierig, wie ein anderes Mehtod (ich) funktioniert.

    – Pandawelt

    12. Mai 2020 um 10:20 Uhr

Benutzer-Avatar
Pravin Divraniya

Antwort von @Kris Roofe macht die Dinge klar. Lassen Sie mich noch etwas hinzufügen.

Spaß Activity.drawer bedeutet, dass wir einen Erweiterungsfunktionsnamen erstellen drawer in Activity Klasse. Aus diesem Grund können wir die Drawer-Methode direkt von einer Activity-Klasse oder einem untergeordneten Element einer Activity-Klasse aufrufen.

Mehr zu Erweiterungsfunktionen hier.

(Setup: DrawerBuilderKt.() -> Einheit = {}) In dieser Aussage können wir die Leistungsfähigkeit von Kotlin-Funktionen höherer Ordnung sehen. Kleine Einführung in Funktionen höherer Ordnung: – It is a function that takes functions as parameters, or returns a function. Also hier Konfiguration param ist eine Funktion, die nichts zurückgibt oder Einheit(Dasselbe wie Void in Java).
DrawerBuilderKt.() bedeutet, dass die Funktion mit dem Objekt von aufgerufen werden kann DrawerBuilderKt Klasse. = {} bedeutet, dass Konfiguration Parameter ist optional. Die Funktion übernimmt also keine Parameter und gibt nichts zurück.

Mehr zu Funktionen höherer Ordnung hier und hier. Mehr zu optionalen Parametern hier.

private val View.viewFinder: View.(Int) -> View? Es speichert eine Funktion in einer Eigenschaft. Hier mehr Infos dazu. Der Rest ist wie oben beschrieben.

Hoffe, das wird helfen.

1121100cookie-checkWas bedeutet „.()“ in Kotlin?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy