2017-07-19 2 views
0
fun lazyProperty(initializer:() -> Int): Int {     
    val result: Lazy<Int> = lazy(initializer) 
    return result.value     
}     

fun main(args: Array<String>) {     
    // 1. 
    val bar: Int = lazyProperty({ 1 + 1 }) 
    // 2. 
    val foo: Int = lazyProperty() { 
    42 
    } 

    println("bar $bar, foo: $foo") 
} 

Ich stolperte vor kurzem über die Syntax eine Funktion in Kotlin Aufruf und ich kann es einfach nicht bekommen: die Faust Option ist klar - es ist ein Lambda ist, aber die zweite sieht nicht wie eine übliche Syntax zum Aufruf einer Funktion mit dem erforderlichen Parameter aus. Die Klammern, in denen normalerweise Parameter platziert werden sollen, sind leer und stattdessen kommt der Funktionsparameter im Körper des Aufrufers! Wie ist es möglich und wozu wird es benötigt?Kotlin: Function-param Implementierung in einem Körper eines Anrufers

Antwort

3

Dies ist ein weiterer Weg, um ein gültiger Lambda übergeben. Nach dem docs:

In Kotlin gibt es eine Konvention ist, dass, wenn der letzte Parameter einer Funktion eine Funktion ist, und Sie einen Lambda-Ausdruck als das entsprechende Argument übergeben, können Sie es außerhalb der Klammern angeben :

lock (lock) { 
    sharedResource.operation() 
} 

Sie können wählen, je nachdem, welcher Ansatz, den Sie bevorzugen.

+3

Beachten Sie auch, dass, wenn eine Funktion nur einen einzigen Funktionsparameter hat, können die Klammern weggelassen werden: 'lazyProperty {42}' – hotkey

1

Dies ist nur Konvention. Wenn der letzte Parameter einer Funktion eine Funktion ist, können Sie das Lambda außerhalb der Klammern übergeben. In Ihrem Fall haben Sie folgende Möglichkeiten:

val bar: Int = lazyProperty({ 1 + 1 }) 
val bar: Int = lazyProperty() { 1 + 1 } 
val bar: Int = lazyProperty { 1 + 1 } 

Alle drei Optionen sind gleich.


Wenn Ihre Funktion würde einen zweiten Parameter haben (an erster Stelle), als die Anrufe könnte wie folgt aussehen:

fun lazyProperty(x: Int, initializer:() -> Int): Int {...} 

val bar: Int = lazyProperty(7, { 1 + 1 }) 
val bar: Int = lazyProperty(7) { 1 + 1 } 

Wenn Ihre Funktion würde einen zweiten Parameter haben (in zweiter aussehen wie diese Position), als die Anrufe könnte:

fun lazyProperty(initializer:() -> Int, x: Int): Int {...} 

val bar: Int = lazyProperty({ 1 + 1 }, 7) 

Also immer versuchen, das Lambda im letzten postulieren zu halten Ion Ihrer Funktion.