2.3.5 스마트 캐스트 : 타입 검사와 타입 캐스트를 조합
(1 + 2) + 4 라는 간단한 산술식을 계산하는 함수를 만들어보자.
식을 트리구조로 저장할 것이다.
노드는 합계(Sum) 나 수(Num) 중 하나다.
Num은 항상 말단 노드지만, Sum 은 자식이 둘 있는 중간 노드다.
Sum 노드의 두 자식은 덧셈의 두 인자다.
Expr 인터페이스에는 두 가지 구현 클래스가 존재한다.
따라서 식을 평가하려면 두 가지 경우를 고려해야 한다.
- 어떤 식이 수라면 그 값을 반환한다.
- 어떤 식이 합계라면 좌항과 우항의 값을 계산한 다음에 그 두 값을 합한 값을 반환한다.
[Java]
// [Java] - 식을 표현하는 클래스 계층
interface Expr {}
class Num implements Expr {
int value;
public Num(int value) {
this.value = value;
}
}
class Sum implements Expr {
Expr left;
Expr right;
public Sum(Expr left, Expr right) {
this.left = left;
this.right = right;
}
}
public class test {
// [Java] - if 연쇄를 사용해 식을 계산하기
public static int eval(Expr expr) {
if (expr instanceof Num) {
return ((Num) expr).value;
} else if (expr instanceof Sum) {
return eval(((Sum) expr).left) + eval(((Sum) expr).right);
} else {
throw new IllegalArgumentException("Unknown expression");
}
}
// 호출 부분!
public static void main(String[] args) {
System.out.println(eval(new Sum(new Sum(new Num(1), new Num(2)), new Num( 4))));
}
}
[Kotlin]
// [Kotlin] - 식을 표현하는 클래스 계층
interface Expr
// value 라는 프로퍼티만 존재하는 단순한 클래스로 Expr 인터페이스를 구현한다.
class Num(val value : Int) : Expr
// Expr 타입의 객체라면 어떤 것이나 Sum 연산의 인자가 될 수 있다.
// 따라서, Num 이나 다른 Sum 이 인자로 올 수 있다.
class Sum(val left : Expr, val right : Expr) : Expr
// [Kotlin] - if 연쇄를 사용해 식을 계산하기
fun eval(e: Expr) : Int {
if (e is Num) {
return e.value
}else if (e is Sum) {
return eval(e.right) + eval(e.left) // 변수 e에 대해서 스마트 캐스트를 사용한다.
}else {
throw IllegalArgumentException("Unknown expression")
}
}
// [Kotlin] - if 중첩 대신 when 사용하기, 바로 리턴값을 대입하기
fun eval(e: Expr) : Int =
when (e) {
is Num -> {
e.value
}
is Sum -> {
eval(e.right) + eval(e.left) // 변수 e에 대해서 스마트 캐스트를 사용한다.
}
else -> {
throw IllegalArgumentException("Unknown expression")
}
}
// 호출 부분
fun main() {
println(eval(Sum(Sum(Num(1), Num(2)), Num(4))))
}
어떤 변수가 원하는 타입인지? 일단 is 로 검사하고 나면,
굳이 변수를 원하는 타입으로 캐스팅 하지 않아도, 마치 처음부터 그 변수가 원하는 타입으로 선언된 것처럼 사용할 수 있다.
하지만, 실제로는 컴파일러가 캐스팅을 수행해준다.
이를 스마트 캐스트라고 부른다.
'Language > Kotlin' 카테고리의 다른 글
[Kotlin IN ACTION] - Kotlin 함수 정의와 호출(확장함수) (0) | 2022.07.18 |
---|---|
[Kotlin IN ACTION] - Kotlin Exception (예외처리) (0) | 2022.07.14 |
[Kotlin IN ACITON] - Kotlin while & for loop (반복문) (0) | 2022.07.14 |
[Kotlin IN ACTION] - Kotlin 클래스와 프로퍼티 (0) | 2022.07.05 |
[Kotlin IN ACTION] - Kotlin 함수와 변수 (0) | 2022.07.04 |