I am not sure how expr which is a reference of an Interface can call the variable declared in Num class variable. I am learning it through kotlin Koans. Can someone explain?
fun eval(expr: Expr): Int =
when (expr) {
is Num -> expr.value
is Sum -> eval(expr.left)+eval(expr.right)
else -> throw IllegalArgumentException("Unknown expression")
}
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Exp
First of all, when you declare a class like this:
class Num(val value: Int) : Expr
it means that class Num implements interface Expr. It means that any instance of Num can be used as an instance of Expr, so function eval can receive an instance of Num as a parameter.
In when operator you check what is the actual implementation of Expr that was used to create instance expr. Branch is Num -> is called when the actual type of expr is Num, so Kotlin automatically recognizes that in this branch expr is an instance of Num, so you can use properties of Num class. This Kotlin feature is called smart cast.
At the beginning, you can improve you code. If you use Sealed class.
Sealed class Expr {
class Num(val value: Int) : Expr()
class Sum(val left: Expr, val right: Expr): Expr()
}
fun eval(expr: Expr): Int =
when (expr) {
is Num -> expr.value
is Sum -> eval(expr.left) + eval(expr.right)
}
After it you don't need to use else block with some unknown exception.
About your question. expr has access to val value, because it's Num object, not Expr. In your example on start you check object in when block, if expr is Num, then you can take var from Num class, if fields of this class are not private.
When you call method eval() you can pass Num or Sum object, if you can pass Num, you can get value in when block, if you pass a var with type Sum, you can get left and right value.
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