Kotlin函数声明:在大括号之前等号

在Kotlin中,函数声明语法允许您在花括号之前写入等号。 考虑这两个例子:

  1. 没有=标志:

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

    通过调用foo()执行正文中的代码。

  2. =号:

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

    在这里,当调用foo()时,什么都不会发生,但是为了让body执行,可以写成foo()()

这两个声明有什么区别, 为什么他们的行为有所不同?


这个问题虽然意义不大,却被作者故意的提出和回答 ,因为在功能定义不正确的情况下,人们已经发现了一些问题。

尽管视觉相似,这两个声明的概念是完全不同的。

  1. 不带等号的函数声明是一个Unit返回函数 (类似于Java的void函数)。

    花括号内的是它的主体,它在函数调用中被执行。 该函数可以用明确指定的Unit重写:

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

    Kotlin不需要Unit返回函数的返回语句和显式返回类型,通常都省略。

  2. 带等号的函数声明是一个单表达式函数 ,它所做的只是返回等号右边的内容。

    一个简单的例子: fun getInt() = 1只是fun getInt() = 1一个简短形式fun getInt(): Int { return 1 }

    foo ,表达式是一个lambda表达式 ,它只被返回, 不被执行

    foo返回类型是() -> Unit ,一个函数本身,因此foo是一个更高阶的函数 。

    没有语法糖和明确的类型, foo可以被重写为

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

    至于使用情况, foo返回的函数可以存储在一个变量中,传递给它, 稍后可以调用它

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

    这也是为什么示例中的foo()()从lambda体执行代码的原因。