今天在 Medium 看到了一个很有趣的小知识,爬上来和大家分享一下。题目是这样的:

 
fun printIt(num: Int) {
    if (num < 0) {
        print("negative")
    } else if (num > 0) {
        print("positive")
    } else {
        print("zero")
    }
}

fun main() {
    printIt(-1)
    print(",")
    printIt(1)
    print(",")
    printIt(0)
}
 

大家可以猜一下答案。

 

A. negative,positive,zero
B. ,positive,zero
C. negative,,zero
D. negative,positive,

 

毫无疑问,大家的答案肯定是 A 。

 

那么?这道题的意义何在呢?

 

好吧,没错,答案就是 A 。可能没有写过代码的同学都能知道是 A 。容我把题目稍作改动。

 

fun printIt(num: Int) {
    if (num < 0) {
        "negative"
    } else if (num > 0) {
        "positive"
    } else {
        "zero"
    }.let { print(it) }
}

fun main() {
    printIt(-1)
    print(",")
    printIt(1)
    print(",")
    printIt(0)
}
 

仔细对比两道题目,模拟一下你的内心独白。

 

这题肯定不会选 A 了,除非博主笨 !

不选 A,这题答案是什么呢?

博主是真笨,这题肯定还是选 A !

 

不妨打开 IDE 执行一下,控制台冷冷清清的输出了  ,positive,zero 。

 

negative 凭空消失了?

 

对于 Kotlin 代码,凡事不决,首先反编译。看看 Java 代码长什么样子。

 

public static final void printIt(int num) {
  if (num >= 0) {
     String var1 = num > 0 ? "positive" : "zero";
     System.out.print(var1);
  }
}
 

没错,negative 的确凭空消失了。

 

再回过头对比一下两次的代码,如下图。

左边的代码在条件判断分支中执行打印语句,符合我们想象中的执行逻辑,这没有问题。

 

右边的代码在 let 代码块中执行打印语句,虽然不符合我们想象中的执行逻辑,但是它仍然打印了 ,positive,zero 。说明这个 let 成功作用在了一个 String 对象上,间接说明了 Kotlin 的 if/else 是有返回值的。

 

那么,为什么第一个 if 的返回值被忽略了呢?因为作用域函数 let 。先来看另一段代码:

 

fun printIt(num: Int) {
    (if (num < 0) {
        "negative"
    } else if (num > 0) {
        "positive"
    } else {
        "zero"
    }).let { print(it) }
}

 

这段代码如你所想,工作正常。因为使用 () 显示指定了执行 let 函数的对象。

 

到这里,你应该也明白上面是怎么回事了。let 的执行上下文遵循了 就近原则 , 下图中的两段代码是等价的。

原文中还有几道有意思的题目,大家可以进去看看,地址:

https://blog.kotlin-academy.com/puzzlers-on-kotlin-academy-week-1-84f42437ee94 。

 


转自:https://mp.weixin.qq.com/s/HVA9vTN5n2QQwE4B6oyuuQ

 

 

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐