我需要在伴侣对象中定义一个val,该伴随对象使用将伴随类作为参数的方法进行初始化。
我想用这些特质来处理这个问题,不要重复自己。 我的问题是,X.getClass与classOf [X]不一样。 第一个是伴随对象的类,第二个是伴随类的类,但我需要直接获取伴随类而不对其进行硬编码。
基本上我需要这样的东西:
trait Foo { } object FooCompanionObject[f <: Foo] { val fClazz = classOf[f] } // Bar's fClass should be classOf[Bar] case class Bar extends Foo; object Bar extends FooCompanionObject[Bar];问题是由于类型擦除我无法获得泛型类
I need to define a val in my companion object which is initialized with a method which takes the companion class as parameter.
I want to handle this with traits to not repeat myself. My Problem ist, that X.getClass ist not the same as classOf[X]. The first is the class of the companion object and the second is the class of the companion class, but I need to get the companion class without hardcoding it directly.
Basically I need something like this:
trait Foo { } object FooCompanionObject[f <: Foo] { val fClazz = classOf[f] } // Bar's fClass should be classOf[Bar] case class Bar extends Foo; object Bar extends FooCompanionObject[Bar];The problem is that I cannot get the class of an generic type due to type erasure
最满意答案
你的代码有几个问题。 首先,正如你已经说过的那样,类型将被擦除,第二个object s( object FooCompanionObject[f <: Foo] )不接受类型参数,第三个object s不能扩展( object Bar extends FooCompanionObject )。 要做你想做的事情,你必须为你的伴侣对象创建一个抽象基类,它需要一个类型参数,如果你愿意,它可以被限制为一个特定的类型,并且必须在ClassTag上进行上下文绑定。 然后,您可以通过调用runtimeClass上的ClassTag来获得运行时类。 最终的解决方案可能如下所示:
import scala.reflect.ClassTag import scala.reflect.classTag trait Foo abstract class Companion[A <: Foo : ClassTag] { val fClazz = classTag[A].runtimeClass } class Bar extends Foo object Bar extends Companion[Bar] scala> Bar.fClazz res2: Class[_] = class BarThere are several problems in your code. First, as you already said, the type will be erased, second objects (object FooCompanionObject[f <: Foo]) don't take type parameters and third, objects can not be extended (object Bar extends FooCompanionObject). To do what you want, you have to create an abstract base class for your companion objects, that takes a type parameter, which may be constrained to a specific type if you like, and has to be context bound on ClassTag. From the ClassTag you can then get the runtime class by calling runtimeClass on it. The final solution could look like this:
import scala.reflect.ClassTag import scala.reflect.classTag trait Foo abstract class Companion[A <: Foo : ClassTag] { val fClazz = classTag[A].runtimeClass } class Bar extends Foo object Bar extends Companion[Bar] scala> Bar.fClazz res2: Class[_] = class Bar更多推荐
发布评论