
Rewrite the following Java code using smart casts and the when expression:
public int eval(Expr expr) {
if (expr instanceof Num) {
return ((Num) expr).getValue();
}
if (expr instanceof Sum) {
Sum sum = (Sum) expr;
return eval(sum.getLeft()) + eval(sum.getRight());
}
throw new IllegalArgumentException("Unknown expression");
}
fun eval(expr: Expr): Int =
when (expr) {
is Num -> TODO()
is Sum -> TODO()
else -> throw IllegalArgumentException("Unknown expression")
}
interface 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)
else -> throw IllegalArgumentException("Unknown expression")
}
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
스마트 캐스트와 when을 활용하여 자바 코드를 코틀린으로 변경하는 문제이다.
Smart cast
is 연산자를 이용해 타입을 확인할 때 만약 특별한 타입으로 확인되면 명시적으로 타입 캐스팅 형자바코드를 보면
expr가 Num 클래스인 경우 expr를 Num으로 형변환 해주고 value를 반환한다.
expr가 Sum 클래스인 경우 expr를 Sum 객체로 캐스팅한 후, 왼쪽과 오른쪽 표현식을 각각 eval 메서드에 다시 넣어서 결과 반환받고 더해서 최종적으로 더한 값을 반환한다.
이러한 자바코드를 코틀린 코드로 변경할 때 스마트 캐스트 is와 람다식을 활용해서 작성해주면 된다.
expr instanceof Num으로 타입을 확인해주고 내부에서 (Num) expr 명시적으로 형변환을 해주던 코드는
is 연산자를 통해서 자동으로 캐스팅되어 형변환 될 수 있다.
