如果我有1个特征和2个对象:
trait MyClass {
type T <: MyClass
def foo(): ClassTag[T] = {...}
}
object ChildClass1 extends MyClass {
type T = String
}
object ChildClass2 extends MyClass {
type T = Option[String]
}
是否可以在MyClass中实现foo(),以便ChildClass1.foo()产生ClassTag [String],而ChildClass2.foo()产生ClassTag [Option]。
如果没有,绕过它最简单的方法是什么?应该注意的是,T的实现可能是内部类/对象,因此黑客反射可能会产生一些副作用。
答案 0 :(得分:0)
我想提出一个肮脏和有缺陷的答案,如果你有任何更好的想法,请告诉我:
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)
}
仅当子类是单个对象时才有效。
答案 1 :(得分: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]]
}