2016-03-16 9 views
19

Kotlinでは、関数宣言構文を使用して中括弧の前に等号を書くことができます。これらの2つの例を考えてみましょう:Kotlin関数宣言:中括弧の前に等号を付けます

  1. =記号なし:

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

    体の内部コードはちょうどfoo()を呼び出すことによって実行されます。 =符号付き

  2. :ここ

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

    foo()が呼び出され、何も起こりませんが、体を得るために1がfoo()()を書くことができます実行します。

これら2つの宣言の相違点は何ですか?どうして違うのですか?


人々が正しくないため、関数の定義の問題を持っているいくつかの質問が既に掲載されているので、この質問は、あまり意味を持つものの、intentionally asked and answered by the authorです。

+2

コトリンまたはIDEにはおそらく検査が必要です。 https://youtrack.jetbrains.com/issue/KT-11461 –

+0

@hotkey oups、申し訳ありません – voddan

答えて

16

視覚的な類似性にもかかわらず、これら2つの宣言のアイデアは全く異なります。

  1. 関数宣言をせずに符号が(Javaのvoid機能に類似)Unit-returning functionです等しいです。

    中括弧の中身は本体です。これは関数呼び出し時に正しく実行されます。関数が明示的に指定Unitで書き換えることができます。

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

    KotlinはUnit -returningの関数のreturn文と明示的な戻り値の型を必要としない、との両方が、通常は省略されています。

  2. 等号付きの関数宣言はsingle-expression functionであり、等号の右にあるものを返すだけです。

    より簡単な例:fun getInt() = 1は、fun getInt(): Int { return 1 }という短い形式です。

    fooでは、式がa lambdaあり、そして唯一を実行していない、返されます。

    戻りタイプがfooであるのは、() -> Unitであり、機能そのものであり、foohigher-order functionです。構文砂糖なしと明示的な型と

    fooは、使用、foo戻り、変数に格納されているの周りに渡され、、後で呼び出すことができることができる機能するよう

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

    のように書き換えることができます。

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

    例でfoo()()ラムダ本体からコードを実行する理由でもあります。