以下を定義した後:
abstract class A {
type T
def print(p: T) = println(p.toString)
}
trait B extends A {
type T <: String
}
予想通り、次のオブジェクトを作成することはできませんT = Int
。
scala> val a = new A with B {type T = Int}
<console>:9: error: overriding type T in trait B with bounds >: Nothing <: String;
type T has incompatible type
val a = new A with B {type T = Int}
^
予想どおり、次のオブジェクトを作成できT = String
ます。
scala> val a = new A with B {type T = String}
a: A with B{type T = String} = $anon$1@692dec
scala> a.print("test")
test
a
値を typeにキャストした後A with B
、メソッドを呼び出すとエラーが発生しますprint
。タイプ フィールドがタイプT
に関する情報を失ったようです (?)。
scala> val b = a.asInstanceOf[A with B]
b: A with B = $anon$1@1927275
scala> b.print("test")
<console>:15: error: type mismatch;
found : java.lang.String("test")
required: b.T
b.print("test")
^
質問 1:型フィールドに関する情報T
がキャスト後に失われるのはなぜですか?
T
よし、型フィールドを型に明示的に設定するキャストでもう一度試しますString
。
scala> val c = a.asInstanceOf[A with B {type T = String}]
c: A with B{type T = String} = $anon$1@1927275
scala> c.print("test")
test
わかりました、これでうまくいきました。
クレイジーなことを試してみましょう:
scala> val d = a.asInstanceOf[A with B {type T = Int}]
d: A with T{type T = Int} = $anon$1@1927275
scala> d.print(3)
3
質問 2:え?特徴は型がStringのサブタイプになるようにB
制限されていましたが、メソッドは整数で動作するようになりました。なぜこれが機能するのですか?T
print