2017-04-19 7 views
1

取得:私は、サブクラスに追加された抽象型の名称提供する特色を作成しようとしている抽象型の名前

trait T { 
    type T 
    def myClassOf[T:ClassTag] = implicitly[ClassTag[T]].runtimeClass 
    def getType = { 
    myClassOf[T].getSimpleName 
    } 
} 

class TT extends T { 
    type T = String 
} 

はしかし、これはコンパイルに失敗します。

Error:(7, 15) not enough arguments for method myClassOf: (implicit evidence$1: scala.reflect.ClassTag[T.this.T])Class[_]. 
Unspecified value parameter evidence$1. 
    myClassOf[T].getSimpleName 
      ^

getTypeメソッドをサブクラスに移動するとうまくいきます。誰かが理由を説明し、サブクラスからこの呼び出しを行う方法があるかどうかを説明できますか?

答えて

4

myClassOf[T]Tを呼び出す時点では、まだ抽象的なので、コンパイラはClassTagを生成できません。 TがわかるまでClassTag[T]の生成を遅らせて修正できます。

trait Trait { 
    type T 
    def myClassOf[A:ClassTag] = implicitly[ClassTag[A]].runtimeClass 
    def getType(implicit tag: ClassTag[T]) = { 
    myClassOf[T].getSimpleName 
    } 
} 

class Sub extends Trait { 
    type T = String 
} 

暗黙のパラメータを追加することは不可能である場合

は、何らかの理由で私は最善の方法は、おそらく、サブクラスで実装するいくつかの方法 getClassTを要求していると思います。戻り値の型は Class[T]なので、サブクラスで間違った実装を提供することは困難です。

trait Trait { 
    type T 
    def getType = { 
    getClassT.getSimpleName 
    } 
    def getClassT: Class[T] 
} 

class Sub extends Trait { 
    type T = String 
    def getClassT = classOf[T] 
} 
+0

感謝を参照してください参照してください。それは理にかなっている。 – jamborta

+0

同じ型の中から 'getType'メソッドを呼び出せる方法はありますか?私は暗黙のパラメータを渡す必要があるように、署名が固定されているメソッドでそれを使用したいと思います。 – jamborta

+0

私はすぐに方法を見ません。 –

0

上記の答えは、スカラ2.10以降は廃止されましたが、 これで、prefferedメソッドはTypeTagまたはClassTagを使用するようになりました。 docs (see below)で説明したように

あなたは今、この種のものを行うには、暗黙的なのparamリストやコンテキスト境界でそれらを使用することができます -

import scala.reflect.runtime.universe._ 

def paramInfo[T: TypeTag](x: T): Unit = { 
    val targs = typeOf[T] match { case TypeRef(_, _, args) => args } 
    println(s"type of $x has type arguments $targs") 
} 

scala> paramInfo(42) 
type of 42 has type arguments List() 

scala> paramInfo(List(1, 2)) 
type of List(1, 2) has type arguments List(Int) 

scala docs on Typetags

api docs

関連する問題