2016-05-19 17 views
0

Wenn ich 1 Zug und 2 Objekte:In Scala, wie auf den ClassTag des implementierten abstrakten Typs in allen Unterklassen verweisen?

trait MyClass { 
    type T <: MyClass 

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

object ChildClass1 extends MyClass { 
    type T = String 
} 

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

ist es möglich, foo() in MyClass zu implementieren, so dass ChildClass1.foo() ergibt ClassTag [Zeichenfolge] und ChildClass2.foo() ergibt ClassTag [Möglichkeit].

Wenn nicht, was ist der einfachste Weg, um es zu umgehen? Es sollte angemerkt werden, dass die Implementierung von T innere Klassen/Objekte sein kann, so dass Hacking-Reflektion einige Nebenwirkungen haben kann.

+0

Warum brauchen Sie überhaupt Reflexion? In Scala gibt es normalerweise einen Weg um ihn herum. – Reactormonk

+0

Ja, obwohl eine ausführlichere und unnötige Art zu wiederholen, was der Compiler bereits wissen sollte – tribbloid

Antwort

0

Ich mag würde eine schmutzige und beeinträchtigte Antwort vorzuschlagen, mich bitte Rat, wenn Sie eine bessere Idee:

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) 
    } 

es funktioniert nur, wenn die Unterklasse ein Singleton-Objekt ist.

0

Ok, es ist möglich, dass ich Ihr Ziel nicht vollständig verstehe, aber von dem, was ich sehen kann, versuchen Sie, ein Merkmal mit einem Obergrenze-Typ zu erstellen, und Sie möchten auch den Typ erhalten Laufzeit, richtig?

Also lassen Sie uns annehmen, dass Sie haben eine Foo Merkmal:

class MyClass // not important 

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

Wenn Sie ein Objekt Implementierung möchten, die Lösung trivial ist, da Sie die Art zum Zeitpunkt der Kompilierung kennen:

class MyClassSubclass extends MyClass // also not important 

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

Aber wenn Sie wollen eine Klasse, dann können Sie das Problem mit der implicitly + Context gebundene Combo in einer gut lesbaren Weise lösen:

+0

Das sieht gut aus, aber in meiner Implementierung kann das def foo: ClassTag weggelassen werden. Einfachheit ist immer wünschenswert – tribbloid