有趣的 Kotlin 0x03:If-else chaining

734 阅读2分钟

最近在 portal.kotlin-academy.com/#/ 上看到很多关于 Kotlin 的有趣的题目。个人觉得很适合 Kotlin 爱好者,感兴趣的小伙伴可自行查阅。 【有趣的 Kotlin 】系列记录自己对每一题的理解。

0x03:If-else chaining

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

fun main(args: Array<String>) {
	printNumberSign(-2)
	print(",")
	printNumberSign(0)
	print(",")
	printNumberSign(2)
}

以上代码,运行结果是什么?可选项:

  1. negative,zero,positive
  2. negative,zero,
  3. negative,,positive
  4. ,zero,positive

思考一下,记录下你心中的答案。

分析

Kotlin 中没有类似于 Java 的三目运算符,取而代之的是 if-else 表达式,所谓表达式,也就是有值的。

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

如上题中,其实是由两个 if-else 组成。

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

其实,只要理解到这里,感觉答案已经比较清晰了。 let 函数作用于它前面的对象,因为第二个 if-else 表达式是有返回值的,所以它作用于第二个 if-else 表达式。 所以题中 printNumberSign 函数等价于另外一种写法:

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

这种写法是不是就很清晰了。其实 Kotlin 中大部分具有迷惑性的代码是因为简略写法

所以,本题的答案是

选项4:,zero,positive

若想让 let 作用于第一个 if-else 表达式,则需要让其前面的内容成为一个被程序识别的整体,加个括号即可:

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

总结

  1. Kotlin 中 if-else 是表达式,是有值的;
  2. Kotlin 中没有三目运算符,使用 if-else 表达式即可;
  3. Kotlin 中 else-if 写法其实本质上是由多个 if-else 表达式组成;
  4. Kotlin 中大部分具有迷惑性的代码是因为简略写法;