【问题标题】:New Instances of Decorated Instances装饰实例的新实例
【发布时间】:2011-01-04 15:44:10
【问题描述】:

我有一组装饰器特征(为了简单起见,这里只有特征T)混合在类(这里是A 的子类)中。

trait T { def i: Int }
abstract class A
type AT = A with T
class B extends A
// class C extends A
// class D extends A
// ...
现在我有一个实例a,例如我将B 类作为AT 类型的实例处理(与Seq[AT] 中的其他A-subclass-AT-instances 一起处理)。
val a: AT = new B with T { val i = 8 }
我怎样才能一般这样装饰:
def toAT(a: A, i: Int): AT = {
 // how to ???
}
我想到的一个明显的解决方案是:
trait T { def i: Int }
abstract class A {
  def asAT(i: Int): AT
}
class B extends A {
  def asAT(ii: Int): AT = new B with T { val i = ii }
}
type AT = A with T
def toAT(a: A, i: Int): AT = a.asAT(i)
但是我不想用一种新方法污染我的课程B, C, ..., Z,而且还有其他装饰,所以对于每个装饰组合,我都需要一个用于所有子类的新方法! 有没有更通用的方法?

编辑: 为什么我需要toAT 方法的一个例子,但仍然使用上面redecorated 方法的明显解决方法:

trait T { def b: Boolean}
type AT = A with T
abstract class A(val i: Int) {
  def changedBy(x: Int): A
  def redecorated(oldAT: AT): AT
}
class B(x: Int) extends A(x) {
  def changedBy(x: Int): A = new B(i * x) 
  def redecorated(oldAT: AT): AT = new B(i) with T { val b = oldAT.b }
}
class C(x: Int) extends A(x) {
  def changedBy(x: Int): A = new C(i * x * x) 
  def redecorated(oldAT: AT): AT = new C(i) with T { val b = oldAT.b }
}
val b = new B(1) with T { val b = true  }
val c = new C(1) with T { val b = false }
val x = 8
val res: Seq[AT] = Seq(b,c) map { at => at.changedBy(x).redecorated(at) }

【问题讨论】:

    标签: scala


    【解决方案1】:

    基本上你做不到。

    另一种方法是使用auto proxy pluginKevin Wright。另请参阅 herehere 了解更多信息。

    【讨论】:

    • 在 Scala 2.9 之前你不会看到该插件正常工作。它涉及基于现有类型信息在现有类中合成新方法——这是一个特别棘手的问题。现在 Scala 主干中有很多有趣的工作正在进行,但这应该会让任何看起来生成合成方法的编译器插件更容易
    • 感谢这个有趣的链接。 Dynamic Mixins 是我想要的。
    • @Kevin:我期待 Scala 2.9
    • 既然 2.9.0RC1 已经发布了,关于自动代理插件有什么消息吗?
    • @Ceki 将@Kevin 添加到评论的开头,以便他收到通知。
    猜你喜欢
    • 1970-01-01
    • 2015-06-24
    • 2019-01-03
    • 1970-01-01
    • 2019-02-03
    相关资源
    最近更新 更多