2016-03-16 14 views
19

In Kotlin, la sintassi della dichiarazione di funzione consente di scrivere il segno di uguale prima delle parentesi graffe. Considerate questi due esempi:Dichiarazione di funzione di Kotlin: equivale a segno prima delle parentesi graffe

  1. Senza = segno:

    fun foo() { 
        bar() 
        println("baz") 
    } 
    

    Il codice all'interno del corpo viene eseguito semplicemente chiamando foo().

  2. Con = segno:

    fun foo() = { 
        bar() 
        println("baz") 
    } 
    

    Qui, quando foo() si chiama, non succede nulla, ma per ottenere il corpo eseguito si può scrivere foo()().

Qual è la differenza in queste due dichiarazioni e perché si comportano in modo diverso?


Questa domanda, pur non avendo molto significato, è intentionally asked and answered by the author, perché alcune domande sono già stati pubblicati in cui la gente ha dei problemi a causa delle definizioni di funzioni errate.

+2

Kotlin o l'IDE probabilmente dovrebbero fare un'ispezione per questo. https://youtrack.jetbrains.com/issue/KT-11461 –

+0

@hotkey oups, scusa – voddan

risposta

16

Nonostante la somiglianza visiva, l'idea di queste due dichiarazioni è completamente diversa.

  1. dichiarazione Funzione senza segno di uguale è una Unit-returning function (simile a void funzioni di Java).

    Ciò che è all'interno delle parentesi graffe è il suo corpo, che viene eseguito direttamente nella chiamata di funzione. La funzione può essere riscritta con Unit esplicitamente specificato:

    fun foo(): Unit { 
        bar() 
        println("baz") 
        return Unit 
    } 
    

    Kotlin non richiede la dichiarazione di ritorno e tipo di ritorno esplicito per Unit funzioni -returning, ed entrambi sono di solito omessi.

  2. La dichiarazione di funzione con segno di uguale è un single-expression function e quello che fa è solo restituire ciò che è a destra del segno di uguale.

    Un esempio più semplice: fun getInt() = 1 è solo una forma più breve di fun getInt(): Int { return 1 }.

    In foo, l'espressione è a lambda, e viene restituito solo, non eseguito.

    Il tipo di reso di foo è () -> Unit, una funzione stessa, e quindi foo è un higher-order function.

    senza zucchero sintattico e con il tipo esplicito, foo può essere riscritta come

    fun foo():() -> Unit { 
        val result:() -> Unit = { bar(); println("baz") } 
        return result 
    } 
    

    quanto riguarda l'uso, la funzione che foo rendimenti possono essere memorizzati in una variabile, passata intorno e può successivamente essere invocata:

    val f = foo() 
    
    f() //equivalent to 
    f.invoke() 
    

    Questo è anche il motivo per cui foo()() nell'esempio esegue il codice dal corpo lambda.