0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kotlin Koans やってみた 9

Posted at

Classes

Smart casts

問題

以下の Java コードを スマートキャストと when 式 を使用して書き換えてください。

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 -> 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

解説

Kotlin 公式ドキュメント > Smart casts

Smart casts

ほとんどの場合、明示的なキャスト演算子を使用する必要はありません。コンパイラが自動的にオブジェクトをキャストしてくれるからです。これをスマートキャストと言います。コンパイラは、イミュータブルな値に対する型チェックと明示的キャストを追跡し、必要に応じて暗黙的な(安全な)キャストを自動的に挿入します。

fun demo(x: Any) {
    if (x is String) {
        print(x.length) // x は自動的に String 型にキャストされる
    }
}

コンパイラは、否定的なチェックが返り値に繋がる場合、キャストが安全であることも認識できるほど賢いです。
if (x !is String) return

print(x.length) // x は自動的に String 型にキャストされる

Control flow

スマートキャストは、if 条件式だけでなく、when 式や while ループでも機能します。

when (x) {
    is Int -> print(x + 1)
    is String -> print(x.length + 1)
    is IntArray -> print(x.sum())
}

ifwhen、または while の条件で変数を Boolean 型として宣言すると、コンパイラがその変数について収集した情報が対応するブロック内でスマートキャストのために利用できるようになります。

これは、ブール条件を変数に抽出するような操作に役立ちます。変数に意味のある名前を付けることで、コードの可読性が向上し、後でその変数を再利用できるようになります。

class Cat {
    fun purr() {
        println("Purr purr")
    }
}

fun petAnimal(animal: Any) {
    val isCat = animal is Cat
    if (isCat) {
        // コンパイラは isCat に関する情報にアクセスできるため、
        // animal が Cat 型にスマートキャストされたことを認識します。
        // そのため、purr() 関数を呼び出せます。
        animal.purr()
    }
}

fun main(){
    val kitty = Cat()
    petAnimal(kitty)
    // Purr purr
}

おわりに

スマートキャストは、型チェックをしたあとに、その型を自動的に適切に型キャストしてくれる仕組みなんですね。難しく感じるのは Java を知らないからなんだろうなー。
is はプリミティブ型でもオブジェクト型でも型チェックに使える点は JavaScript より便利そうだなって感じる。


← 前回の記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?