这个问题格外短,也格外简单。
fun hello() = {
println("Hello World")
}
fun main() {
hello()
}
打印结果是:
- 无法编译
- 打印"Hello World"
- 什么也不发生
- 其他情况
暂且不纠结答案,先来回顾一下 Kotlin 中是如何声明函数的。
- Kotlin 使用 fun 关键字来声明函数,如下所示:
fun hello() = "Hello World"
Kotlin 会自动推导函数返回值,上面的代码定义了一个返回值是 String 的函数。
那么… 下面的代码正确吗?
fun hello3() {
return "Hello Wrold"
}
hello2() 是不能正常编译的。因为如果显式使用了 return,也必须显式指定返回值类型。
- 到这,注意两个点:
1、Kotlin 会自动推导函数返回值类型,但显式 return 也必须显式声明返回值类型。
2、使用 = 定义函数可以省略函数返回值类型。
回到原题:
fun hello() = {
println("Hello World")
}
这就很明了了,声明了一个返回值类型可自动推导的函数 hello() ,其返回值类型就是 = 后面的 {…} 。
这对大括号是什么类型呢?熟悉kotlin语法应该知道 {} 是Lambda表达式。
Lambda又是什么类型呢?kotlin中Lambda是函数类型的对象。函数类型的对象,有点不好理解。
在 Kotlin 中,函数也是对象,但又不是传统意义上的对象。每个函数对象都有自己的函数类型,这个类型又有很多种,由函数的参数类型和返回值类型共同决定。要注意一点,Lambda 表达式的最后一行就是其返回值。
val a: () -> Unit = { }
val b: (Int) -> String = { i -> "" }
val c: (Int, String) -> Int = { i, s -> 1 }
val d: (Int) -> ((Int) -> Unit) = { i -> {} }
上图的 a、b、c、d 是四个具有不同函数类型的函数对象。其中 d 是一个参数是 Int , 返回值类型是函数类型 (Int) -> Unit的函数对象。
再次回到开头的代码:
fun hello() = {
println("Hello World !")
}
妥妥的,hello函数返回了一个Lambda,它的函数类型是() -> Unit。对于返回值或者参数是函数类型的函数,又称之为 高阶函数。上面的代码等价于如下代码:
fun hello(): () -> Unit {
return { println("Hello World !") }
}
那么,如何真正的打印出 Hello Wrold呢?使用hello()()或者hello().invoke()。