В Scala, как я могу посоветовать свои собственные методы? - PullRequest
2 голосов
/ 23 октября 2011

Я хочу сделать это:

trait Renderable {
    def render: String
}

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

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

Но это не работает, потому что порядок линеаризации ставит Паренс после Foo (Foo всегда приходит, конечно), поэтому Паренс не может посоветовать Foo.render.

В итоге я делаю это:

trait FooRender {
    def render = "Hello"
}

object Foo extends FooRender with Parens {
}

Но иногда я действительно не хочу этого делать, потому что это ломает вещи. Как Насколько я могу судить, порядок линеаризации - единственное, что мешает, но я не знаю, как это изменить. Что может сделать это чище?

1 Ответ

2 голосов
/ 23 октября 2011

Как насчет разделения логики представления (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, поскольку вам нужно реализовать черту во время создания, но если вы можете контролировать создание экземпляра, это может сработать:).

Я почти уверен, что иначе это сделать невозможно (кто-то, пожалуйста, поправьте меня, если я ошибаюсь)

...