2017-09-20 10 views
0

基本型の内部に完全型(型パラメータ付き)を取得することは可能ですか?次の例は、問題を示しています。 TODOを参照してください:基本クラス内にパラメータを持つ型を取得する方法

import scala.reflect.api.Types 

abstract class BaseClass { 
    def getType: Type = ??? //TODO how to implement 
} 

case class Child1[M](model: M) extends BaseClass 

case class Child2(p: Int) extends BaseClass 

... 

val c1 = Child1("Hello") 
val c2 = Child2(10) 

val xs = List(c1, c2) 

xs foreach { e: BaseClass => 
    println(e.getType) 
} 

// out: 
// com.project.Child1[java.lang.String] 
// com.project.Child2 
// ... 

答えて

2

あなたは、基本クラスに型パラメータを追加することができます

abstract class BaseClass[A: TypeTag] { 
    def getType = s"${getClass.getName}[${typeOf[A]}]" 
} 

case class Child1[M: TypeTag](model: M) extends BaseClass[M] 
case class Child2(p: Int) extends BaseClass[Unit] 

... 

xs foreach {e => println(e.getType)} 
+0

を与える 'ケースクラスChild3 [M、N](モデル:M、ノード1:N)はBaseClass'を拡張しますか? – talex

+0

'BaseClass'に' getType'を実装したい場合、 'BaseClass'は' M'、 'N'などの型を知る必要があります。もちろん、それぞれのクラスで 'getType'を実装することができます。必要なのは、それぞれの型パラメータに対して' TypeTag'だけです。 –

+0

また、WeakTypeTagを使用することもできます。 –

1

私はあなたに次の解決方法を提案することができます。

trait BaseClass { 
    val realType: Any 

    def getType: String = realType.toString() 
} 

case class Child1[M: TypeTag](model: M) extends BaseClass { 
    override val realType = typeTag[Child1[M]] 

} 

case class Child2(p: Int) extends BaseClass { 
    override val realType = typeTag[Child2] 
} 

それはまさにあなたが望む結果をない作ります、しかしかなり近い。

val xs = Seq[BaseClass](Child1[String](""), Child2(1)) 
xs.foreach { e => println(e.getType) } 

は場合に何をする次の出力に

TypeTag[test.Child1[String]] 
TypeTag[test.Child2] 
関連する問題