2016-05-19 5 views
0

I 1つの形質及び2つのオブジェクトがある場合:Scalaでは、すべてのサブクラスで実装された抽象型のClassTagを参照する方法は?

trait MyClass { 
    type T <: MyClass 

    def foo(): ClassTag[T] = {...} 
} 

object ChildClass1 extends MyClass { 
    type T = String 
} 

object ChildClass2 extends MyClass { 
    type T = Option[String] 
} 

それはFOOを実現することができる()MyClassの中、ChildClass1.foo()はClassTag [文字列]を得、及びChildClass2.foo()はClassTagを生成するように[オプション]。

もしそうでない場合、それを迂回する最も簡単な方法は何ですか? Tの実装は内部クラス/オブジェクトなので、ハッキングの反映にはいくつかの副作用があることに注意してください。

lazy val mf: ClassTag[T] = { 

    val clazz = this.getClass 
    val name = clazz.getName 
    val modifiedName = name + "T" 
    val reprClazz = Utils.classForName(modifiedName) 

    Manifest.classType(reprClazz) 
    } 

サブクラスはシングルトンオブジェクトである場合にのみ動作します:

+0

最初に反射が必要なのはなぜですか? Scalaでは、通常、その周りに道があります。 – Reactormonk

+0

はい、コンパイラが既に知っているべきことを繰り返すために、より冗長で不必要な方法です。 – tribbloid

答えて

0

私は汚れや障害答えを提案したい、あなたが任意のより良いアイデアを持っているなら、私にアドバイスをしてください。

0

私はあなたの目標を完全には理解していない可能性がありますが、私は見ることができますが、上限型の形質を作成しようとしています。ランタイム、正しい?

それでは、あなたがFoo形質を持っていると仮定してみましょう:

class MyClass // not important 

trait Foo[T <: MyClass] { 
    def foo: ClassTag[T] 
} 

あなたがオブジェクトの実装をしたい場合は、コンパイル時にタイプを知っているので、解決策は、簡単です:

class MyClassSubclass extends MyClass // also not important 

object FooObject extends Foo[MyClassSubclass] { 
    def foo: ClassTag[MyClassSubclass] = ClassTag(classOf[MyClassSubclass]) 
} 

しかし、もしクラスが必要な場合は、implicitly +コンテキストバインドされたコンボで問題を解決できます。

class FooImpl[T <: MyClass : ClassTag] extends Foo[T] { 
    def foo: ClassTag[T] = implicitly[ClassTag[T]] 
} 
+0

これはうまく見えますが、私の実装ではdef foo:ClassTagを省略できます。シンプルさは常に望ましい – tribbloid

関連する問題