这是海外一位 Kotlin GDE 大佬,在 Twitter 上分享的一段代码,我觉得非常的有意思,代码如下所示,我们花 10s 思考一下,输出结果是什么。
fun printE() = { println("E") }
fun main() {
if (true) println("A")
if (true) { println("B") }
if (true) {
{ println("C") }
}
{ println("D") }
printE()
when {
true -> { println("F") }
}
}
在 Twitter 评论区中也能看到很多不同的答案。
实际上最后输出结果如下所示。
A
B
F
不知道你第一次看到这么多混乱的花括是什么感觉,当我第一次看到这段代码的时候,我觉得非常的有意思。
如果在实际项目中有小伙伴这么嵌套花括号,我相信肯定会被拉出去暴晒。但是细心观察这段代码,我们能学习到很多 Kotlin 相关的知识点,我们先来说一下为什么最后输出的结果是 A B F。
下面图中红色标注部分,if 表达式、 when ... case 表达,如果表达式内只有一行代码的话,花括号是可以省略的,程序执行到代码位置会输出对应的结果, 即 A B F。
那为什么 C D E 没有打印,因为图中绿色部分是 lambda 表达式,在 Kotlin 中 lambda 表达式非常的自由,它可以出现在很多地方比如方法内、 if 表达式内、循环语句内、甚至赋值给一个变量、或者当做方法参数进行传递等等。
lambda 表达式用花括号包裹起来,用箭头把实参列表和 lambda 函数体分离开来,如下所示。
{ x: Int -> println("lambda 函数体") }
如果没有参数,上面的代码可以简写成下面这样。
{ println("lambda 函数体") }
而 C D E 的输出语句在 lambda 函数体内, lambda 表达式我们可以理解为高阶函数,在上面的代码中只是声明了这个函数,但是并没有调用它,因此不会执行,自然也就不会有任何输出。现在我将上面的代码做一点点修改,在花 10s 思考一下输出结果是什么。
fun printE() = { println("E") }
fun main() {
if (true) println("A")
if (true) { println("B") }
if (true) {
{ println("C") }()
}
{ println("D") }()
printE()()
when {
true -> { println("F") }
}
}
最后的输出结果是:
A
B
C
D
E
F
应该有小伙伴发现了我做了那些修改,我只是在 lambda 表达式后面加了一个 (),表示执行当前的 lambda 表达式,所以我们能看到对应的输出结果。如下图所示,
lambda 表达式最终会编译成 FunctionN 函数,如下图所示。