【问题标题】:Anonymous subclass of a parametric type by the use of ClassTag context bound通过使用 ClassTag 上下文绑定的参数类型的匿名子类
【发布时间】:2015-05-30 01:42:53
【问题描述】:

给定一个给定特征的具体类

trait Trt {
    val x: Int
}

class C extends Trt {
    val x: Int = 3
}

我想创建一个参数类型的匿名类的对象,以覆盖属性x

abstract class SomeClass[T <: Trt : ClassTag] {
   def f: Unit = {
      val original = new C

      //Is this even possible?
      val withOverridenX = new T { override val x = 42}

      assert(original.x != withOverridenX.x)
   }
}

问题是编译器一直报如下错误:

>> Error:(26, 35) class type required but T found

实例化匿名类是否可以扩展参数类型类?

我知道问题在于T 是一个类型而不是一个类,我想知道是否有可能,感谢 ClassTag 有界上下文,是否可以实例化 withOverridenX

【问题讨论】:

  • @sjrd 有没有办法,例如使用 ClassTag,能够实例化一个参数类型的匿名类(是的,我知道它是一种类型)在运行时提供类信息,并且以某种方式,使用它?
  • 不,没有办法做到这一点,即使是ClassTag。你需要一个TypeTag 和编译时反射(宏)来做到这一点,我猜(我不完全知道如何)。
  • 感谢您的 cmets 并祝贺 Scala.js,它帮助我说明了 Scala for mi 博客的一些用途:(只是示例,不是博客)orionsword.no-ip.org/demos/pi_scalajsorionsword.no-ip.org/demos/sierpinski_publish
  • @sjrd 只是为了记录,我发现了一个使用 Scala 反射的肮脏解决方法(下面的自动答案)

标签: scala


【解决方案1】:

你不能实例化T,因为它在运行时是未知的,只是在编译时。 ClassTag 只会让您通过runtimeClass 方法访问TClass 对象。但仅此而已,您不能通过调用new 子类化T,因为例如没有证据表明T 具有无参数构造函数。

【讨论】:

  • 是的,但这就是为什么我试图使用上下文绑定给出的ClassTag 的证据。
  • 我详细阐述了一点,见上文。
【解决方案2】:

我找到了一种解决方法,可以完全按照我的意愿去做:获取C 的实例(或C 的子类),x 的值与其声明时给出的值不同.

每当有人想滥用编程语言时,通常都会求助于反思。从 2.10 版开始,Scala 提供了its own reflection 功能(Java 除外),因此可以将x 更改为withOverridenX

import scala.reflect.runtime.universe._

abstract class SomeClass[T <: Trt : TypeTag ] {
   def f: Unit = {
      val original = new C
      val withOverridenX = new C

      //This gets the term representation for the attribute 'x'...
      val xTerm = typeOf[T].declaration(newTermName("x")).asTerm

      //... which can be used to reflect the attribute:
      val m = runtimeMirror(getClass.getClassLoader)
      val reflectedC = m.reflect(withOverridenX)
      val reflectedX = reflectedC.reflectField(xTerm)

      reflectedX.set(42)

      assert(original.x != withOverridenX.x)
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多