Kotlin函数声明:在大括号之前等号
在Kotlin中,函数声明语法允许您在花括号之前写入等号。 考虑这两个例子:
-
没有
=
标志:fun foo() { bar() println("baz") }
通过调用
foo()
执行正文中的代码。 -
带
=
号:fun foo() = { bar() println("baz") }
在这里,当调用
foo()
时,什么都不会发生,但是为了让body执行,可以写成foo()()
。
这两个声明有什么区别, 为什么他们的行为有所不同?
这个问题虽然意义不大,却被作者故意的提出和回答 ,因为在功能定义不正确的情况下,人们已经发现了一些问题。
尽管视觉相似,这两个声明的概念是完全不同的。
-
不带等号的函数声明是一个
Unit
返回函数 (类似于Java的void
函数)。花括号内的是它的主体,它在函数调用中被执行。 该函数可以用明确指定的
Unit
重写:fun foo(): Unit { bar() println("baz") return Unit }
Kotlin不需要
Unit
返回函数的返回语句和显式返回类型,通常都省略。 -
带等号的函数声明是一个单表达式函数 ,它所做的只是返回等号右边的内容。
一个简单的例子:
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体执行代码的原因。