CLOVER🍀

That was when it all began.

Scalaのアップキャスト?

とあるエントリを見て、Scalaのアップキャストっぽい構文を見て、「そんなのあったの?」ってところから。asInstanceOfがキャストと思ってましたけど、そういればこれってダウンキャストでしか使ったことないですしね…。

ちょっと試してみます。

REPLを起動。

$ scala
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.

継承関係のあるクラスを定義。

scala> class A
defined class A

scala> class B extends A
defined class B

型をBとして変数bを定義。

scala> val b: B = new B
b: B = B@2d917ec

scala> b
res0: B = B@2d917ec

B型だと思っていますね。

ここで、こんな構文を書くとAにアップキャストできるみたいです。

scala> (b: A)
res1: A = B@2d917ec

知らなかった…。

ダウンキャストには使えないみたいです。

scala> val a: A = new B
a: A = B@3db30d10

scala> (a: B)
<console>:11: error: type mismatch;
 found   : A
 required: B
              (a: B)
               ^

ダウンキャストは、普通にパターンマッチか

scala> a match { case cb: B => cb }
res6: B = B@3db30d10

asInstanceOfですね。

scala> a.asInstanceOf[B]
res3: B = B@3db30d10

asInstanceOfでもアップキャストはできるみたいですが。

scala> b.asInstanceOf[A]
res10: A = B@2d917ec

パターンマッチは微妙?

scala> b match { case ca: A => ca }
res9: B = B@2d917ec

この時、A型で受けとればAとできますが、まあそんなことしないですね。

scala> val a2: A = b match { case ca: A => ca }
a2: A = B@369a9f38

なるほど…。

REPLで試していますが、Scalaソースコードをちゃんと書き起こしてもこんな感じになりました。

とりあえず、覚えておきましょう。