この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
毎日Kotlinシリーズです。
このシリーズを初めての方はこちらです。「毎日Kotlin」はじめました | Developers.IO
問題
JavaからKotlinに変換してみよう。
Rewrite the following Java code using smart casts and 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
狙い
ここで考えて欲しい問題の意図はなんだろうか?
スマートキャストはとっても便利です。よしなにやってくれるので助かります。今回の例だけでなく、いろんな場面でスマートキャストをしてくれるので、「え?すでにキャスト済み?」とびっくりすることも多々あります。JetBrains神ありがとう。
解答例
fun eval(expr: Expr): Int =
when (expr) {
is Num -> expr.value
is Sum -> eval(expr.left) + eval(expr.right)
else -> throw IllegalArgumentException("Unknown expression")
}
is が instanceof と同じ役割で使っています。それ以降に使う場合はすでにキャストされて使えるので便利です。 ((Num) expr)こんな感じでいちいちキャストする必要ありません。
型をチェックしたら、キャストしたのと同様に扱えます。
補足
「え?すでにキャスト済み?」とびっくりする例があります。これをうまいこと使って、コンパイルレベルで安全にコードを書いていきましょう。
fun foo(str: String?) {
if (str != null) {
//?がいらない。not nullであることが推論され、スマートキャストされます
str.length
}
str ?:return
//?がいらない。not nullであることが推論され、スマートキャストされます
str.length
}
あとがき
Day10.でまたお会いしましょう。