The question may sound silly, but there is no typo in it.
fun test(): Any {
return return true
}
This is actually possible in Kotlin. Although the compiler warns about
Unreachable code
for the outer return. But this is just a warning.
I don't want to compare Java with Kotlin, but I was interested whether the same would work in Java.
public class Test {
// ...
static int test() {
return return 1;
}
}
It does not!
/Test.java:8: error: illegal start of expression
return return 1;
^
/Test.java:8: error: not a statement
return return 1;
^
2 errors
Why was Kotlin designed this way?
Kotlin has generic Pair and Triple types that can return two or three values from the function.
Returns and jumps Kotlin has three structural jump expressions: return by default returns from the nearest enclosing function or anonymous function. break terminates the nearest enclosing loop. continue proceeds to the next step of the nearest enclosing loop.
return@ is a statement in Kotlin which helps the developers to return a function to the called function. In simple words, return@ can return any value, anonymous function, simple inline function, or a lambda function.
return
is an expression in Kotlin, with a return type of Nothing
, the type that acts as a subtype of all other types. This enables you to, for example, do this in a type safe way and without extra lines of null
checks:
fun getInt(): Int? = ...
fun printInt() {
val int: Int = getInt() ?: return
println(int)
}
The type of getInt() ?: return
can be Int
here, because that's the closest common supertype of the two sides of the Elvis operator, thanks to Nothing
being a subtype of Int
.
The same thing applies for throw
, which you can also use neatly with the Elvis
operator to indicate that you want to cancel execution on a null
value without having to worry about types later.
This results in an odd quirk where things like
fun x(): Int {
return return throw return throw throw return 0
}
are valid syntax, because the Nothing
type makes each of the expressions valid read from right to left. What will actually happen is that return 0
will execute and the rest of the code will never be reached, as the compiler warns.
Because the return
statement is an expression that returns Nothing
. As a result, the following also compiles:
fun main(args: Array<String>) {
val r = return
}
It's stated in the docs:
Kotlin has three structural jump expressions:
return
. By default returns from the nearest enclosing function or anonymous function. [...]All of these expressions can be used as part of larger expressions:
val s = person.name ?: return
The type of these expressions is the
Nothing
type.
Since Nothing
is a subtype of any other type, it has the power of making weird statements, like the one in your question, valid although they appear to be very wrong...
There was actually a funny talk at KotlinConf taking a look at interesting things like the following:
fun getText(): String {
val s = return throw return "Hello"
}
println(getText())
//prints "Hello"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With