19.0503

スマートキャスト(Smart Casts)

スマートキャストとは、例えば、Java では、プログラマが、コードに、キッチリ書かないと、
たとえ、「is 関係(is演算子で true になる)」 が、成り立っていても、
いけなかったのですが、Kotlin言語 の、コンパイラは賢くて、かなりの部分 を、
文脈から判断してくれます。
(「キッチリ書かないと」 というのは、「キッチリ目的の型に、キャストしないと/変換しないと」
 という意味です)
「かなりの部分を」 と言うのは、私が、スマートキャスト を、信じすぎていて、
そこまでは、無理だったか、、という部分があったからです。

ここでは、
  Kotlinで書いたコード
  Java流に、Kotlinで書いたコード  / (Type) -> as ですが.
を比べて、Kotlinコンパイラ の、優れているところを見ていきます。

どうして、比べるのかというと、そうしないと、Kotlin が、優れていることが、分からないと思います。
Kotlin から始めた人にとっては、あるタイプ(型) が、あのタイプ と、is関係 が成り立つのは、
文脈から当然じゃないかと、思われると思いますが、
それが出来るようになったのだから、Kotlin のコンパイラ は、優秀なのです。

まずは、スマートキャスト を使って書いたコードです。
このコードの、19~21行目 に、注目してください。

今度は、ライクJava(Javaのようなコード)で、書いた例です。
このコードも、19~21行目 に、注目してください。

「ライクJava」 の、コードでは、
   anyObj as Car
など、3つの部分に対して、軽い警告をしています。
  No cast Needed:キャストする必要はありません
これは、
  is Car(Car型ですか?:正しければ、true を、返す)
  is Animal
  is Language
で、チェックしているのに、
  anyObj as Car
   (Car型に 変換/キャスト できれば、Car型になり、
    失敗すれば、ClassCastException例外 を投げる)
  anyObj as Animal
  anyObj as Language
と、わざわざ、キャストするのは、無駄ですよ、、と言っているわけです。
でも、Java などでは、キャストするのが、当たり前だったのです。

Kotlin言語 では、キャストするコードは書かかずに、
  直接、anyObj で、関数 を、呼んでいます。


ただし、期待しすぎては、いけないようです
ただし、スマートキャスト に、期待は、しすぎない方がいいと思います。
最初書いたのは、こんなコードでした。
きっと、Kotlinのコンパイラなら、
  showName()
を、分かってくれると思ったのですが、、
  unsolved reference: showName: 未解決の参照: showName
だそうです。
これは、危ないコードになる危険性から、こういう仕様になっているのかもしれません。
いずれにしても、
  型チェック は、自分でやること
が、大切だと思われます。
  あくまで、スマートキャスト とは、is関係が成り立てば、キャストはしなくてもいいよ
という事のようです。



まとめ
・ スマートキャスト とは、is関係 が成り立つ時、コンパイラが判断してくれるので、
 プログラマが、キャストするコード を、書かなくてもよいことである。
・ ただし、やらなくてもいいのは、「キャストするコード を書くこと」 であって、
 「型チェックをしなくてもいいというわけではない」。