2017-07-19 4 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") 
} 

J'ai récemment trébuché sur la syntaxe d'appeler une fonction dans Kotlin et je ne comprends pas: l'option poing est clair - c'est un lambda, mais le second ne ressemble pas à une syntaxe habituelle d'appeler une fonction avec le paramètre requis. Les parenthèses où normalement les params doivent être placés sont vides et à la place le paramètre de fonction vient dans le corps de l'appelant! Comment est-ce possible et pour quoi est-ce nécessaire?Kotlin: mise en œuvre Fonction-param dans un corps d'un appelant

Répondre

3

Ceci est une autre façon valide de passer un lambda. Selon la docs:

En Kotlin, il existe une convention que si le dernier paramètre à une fonction est une fonction, et vous passez une expression lambda comme argument correspondant, vous pouvez spécifier à l'extérieur des parenthèses :

lock (lock) { 
    sharedResource.operation() 
} 

vous pouvez choisir selon l'approche que vous préférez.

+3

Notez également que si une fonction n'a qu'un seul paramètre fonctionnel, les parenthèses peuvent être omises: 'lazyProperty {42}' – hotkey

1

Ceci est juste une convention. Si le dernier paramètre d'une fonction est une fonction, vous pouvez passer le lambda en dehors des parenthèses. Dans votre cas, vous avez les options suivantes:

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

Les trois options sont les mêmes.


Si votre fonction aurait un second paramètre (à première position), que les appels pourraient ressembler à ceci:

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

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

Si votre fonction aurait un second paramètre (à la deuxième la position), que les appels pourrait ressembler à ceci:

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

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

donc toujours essayer de garder le Lambda au dernier posit l'ion de votre fonction.