2
class S
class A extends S
class B extends S

class ClassWithTypeParameter[+T]

val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]

値 a の型パラメーターに使用されるサブクラスの型をどのように判断できますか?

4

2 に答える 2

3

タイプ eraserのため、できません。ただし、これを行うあなたの試みは誤解から形成されていると私は主張します。

  • 型システムのポイントは、コンパイラがプログラムの正確性についてより強力に推論できるようにすることです。
  • 静的型システムでは、各参照には変更できない型があります

プログラムには 1 つの参照がaあり、この参照の型は ですClassWithTypeParameter[S]。それか。は。全て。コンパイラは、この参照で何ができるかを知ることができます。型は純粋にコンパイラ用です。実行時aが である値に割り当てられたという事実ClassWithTypeParameter[A]は無関係です。


これをある程度近似する(消去によって制限される) 方法の 1 つは、マニフェストを使用することです (2.10 では別のものと呼ばれます)。

class ClassWithTypeParameter[+T: Manifest] { def erasure = manifest[T].erasure }

次に、erasureどちらがあなたを取り戻すかを呼び出すことができますjava.lang.Class。何度も言いますが、これは限定的です。クラスはと同じものではなく、たとえば、型と区別する方法はありませClassWithTypeParameter[List[Int]]ん。ClassWithTypeParameter[List[Double]]

于 2012-06-25T23:02:56.253 に答える
2

以下は (リフレクションのほとんどの使用法と同様に) 悪い考えですが、機能します:

class ClassWithTypeParameter[+T: Manifest] {
  def paramIs[V: Manifest] = manifest[T] == manifest[V]
}

これにより、次のことがわかります。

scala> val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
a: ClassWithTypeParameter[S] = ClassWithTypeParameter@6493c09c

scala> a.paramIs[A]
res0: Boolean = true

scala> a.paramIs[S]
res1: Boolean = false

scala> a.paramIs[B]
res2: Boolean = false

と:

scala> val i = new ClassWithTypeParameter[List[Int]]
i: ClassWithTypeParameter[List[Int]] = ClassWithTypeParameter@260702ee

scala> i.paramIs[List[Int]]
res3: Boolean = true

scala> i.paramIs[List[Double]]
res4: Boolean = false

とを使用して同様のparamSubtypeOfparamSupertypeOfメソッドを書くことができます。Manifest<:<>:>

Scala 2.10 (Milestone 4 以降) では、より柔軟に型を取得する方法があります。

class ClassWithTypeParameter[+T: TypeTag] {
  def paramType = reflect.runtime.universe.typeTag[T].tpe
}

a.paramType.parentsこれで、すぐにスーパータイプを取得するようなものを書くことができます。

于 2012-06-25T23:37:56.920 に答える