为什么“返回”在Kotlin中返回“返回”?

这个问题可能听起来很愚蠢,但是没有错字。

fun test(): Any { return return true } 

这在Kotlin中实际上是可能的。 虽然编译器警告

无法访问的代码

为外面的回报。 但这只是一个警告。

我不想比较Java和Kotlin,但我有兴趣是否可以在Java中使用。

 public class Test { // ... static int test() { return return 1; } } 

它不是!

/Test.java:8:错误:expression式的非法开始
返回1;
^
/Test.java:8:错误:不是一个语句
返回1;
^
2错误

为什么Kotlin是这样设计的?

return是Kotlin中的一个expression式,其返回types为Nothing ,作为所有其他types的子types。 例如,这样可以以types安全的方式执行此操作,而不需要额外的null行检查:

 fun getInt(): Int? = ... fun printInt() { val int: Int = getInt() ?: return println(int) } 

getInt() ?: return的types可以是Int ,因为这是Elvis运算符两边最接近的常见超types,这要归功于NothingInt的子types。

同样的事情适用于throw ,你也可以使用Elvis操作符来整齐地使用它来表示你想取消null值的执行,而不用担心以后的types。

这导致了一个奇怪的怪事,像事情

 fun x(): Int { return return throw return throw throw return 0 } 

是有效的语法,因为Nothingtypes使得每个expression式有效地从右向左读。 实际上会发生的是return 0将会执行,其余的代码将永远不会被编译器警告。

因为return语句是一个返回Nothing的expression式。 结果,下面还编译了:

 fun main(args: Array) { val r = return } 

这是在文档中陈述:

Kotlin有三个结构跳跃expression式:

  • return 。 默认情况下从最近的封闭函数或匿名函数返回。 […]

所有这些expression式都可以用作较大expression式的一部分:

 val s = person.name ?: return 

这些expression式的types是Nothingtypes。

由于Nothing任何其他types的子types,它有权作出奇怪的声明,就像你的问题,有效,虽然他们似乎是非常错误的… …

在KotlinConf上实际上有一个有趣的谈话,看看下面这些有趣的事情:

 fun getText(): String { val s = return throw return "Hello" } println(getText()) //prints "Hello"