2

我想做这个:

trait Renderable {
    def render: String
}

trait Parens extends Renderable {
    abstract override def render = "(" + super.render + ")"
}

object Foo extends Renderable with Parens {
    def render = "Hello"
}

但这不起作用,因为线性化顺序将 Parens 放在 Foo 之后(当然,Foo 总是出现)所以 Parens 不能建议 Foo.render。

我最终这样做:

trait FooRender {
    def render = "Hello"
}

object Foo extends FooRender with Parens {
}

但有时我真的不想这样做,因为它会破坏事情。据我所知,线性化顺序是唯一的障碍,但我不知道有什么方法可以改变它。什么可以使这个更清洁?

4

1 回答 1

2

如何分离表示逻辑(render)和实际内容(value)?

trait Renderable {
  def value : String
  def render = value // default presentation logic, simple rendering.
}

trait Parens extends Renderable {
  override def render :String = "(" + value + ")" // parens rendering.
}

object Foo extends Parens {
  def value = "Hello"
}

println(Foo.render) // prints '(Hello)'

编辑

找到了一种几乎可以做你想做的事情的方法,看看:

trait Renderable {
  def render: String
}

trait Parens extends Renderable {
  abstract override def render = "(" + super.render + ")"
}

class Foo extends Renderable {
  def render = "Hello"
}

val foo = new Foo with Parens
println(foo.render)

您不能使用,object因为您需要在创建时实现特征,但如果您可以控制实例创建,那么这可能会起作用:)。

我很确定否则不可能这样做(如果我错了,请有人纠正我)

于 2011-10-23T02:38:44.567 回答