This is a question on Type Inference that I posted...
# announcements
v
This is a question on Type Inference that I posted on StackOverflow. First guess the answer and then look at the SO answer. I understand that Kotlin is a statically-typed language, and all the types are defined/inferred at the compile time itself. Here is a
when
expression that returns different types:
Copy code
fun main(){

        val x = readLine()?.toInt() ?: 0

        val y = when(x){
            1 -> 42
            2 -> "Hello"
            else -> 3.14F
        }

        println(y::class.java)
}
During runtime (Kotlin 1.3.41 on JVM 1.8) this is the output: When
x
= 1, it prints
class java.lang.Integer
When
x
= 2, it prints
class java.lang.String
Otherwise, it prints
class java.lang.Float
When does the compiler determine the type of
y
? Or, how does the compiler infers the type of
y
during compile-time? Question on StackOverflow: https://stackoverflow.com/q/58479824/816416
p
I think the compiler determines
y class
to be the upper bound class that cover all the when branches return types. Or in other words, the super class that is common to all branches result. Now
KClass<T>.java
is a runtime function call. So it is acting on the actual returned type instance.
👍 2
✔️ 3
a
Using reflection, you get actual class of which instance is of, while in runtime type maybe any supertype, you can declair any integer while storing it as Any type, you cannot do any operation with int since runtime doesn't know about it but if you try using reflection you can actually get the real name of the class of which the instance is of.
✔️ 1
m
Compile-time type of y is Any. But runtime type can be anything that extends Any. You print runtine type, not compile-time type.
✔️ 1
s
so just to be very explicit:
when
doesn’t return different types, it returns a value of typ
Any
. So you wouldn’t be able to call
y.substring(..)
without casting
y
even if
x=2
.
v
@Stephan Schroeder AFAIK,
when
returns the nearest supertype of all branches. In this case,
Any
. If we consider classes
class Foo
,
class Bar: Foo
,
class Baz: Foo
, and a
when
returns
Bar
and
Baz
in different branches, then the inferred type will be
Foo
.
@Stephan Schroeder Also you are right, we must cast
y
to
String
before we call
y.subString()