Можно ли изменить контекст черты на тип, объявленный в качестве параметра типа? - PullRequest
1 голос
/ 24 февраля 2012

То, что я хотел бы выполнить, выглядит примерно так:

class Foo( val bar: String = "Hello!" ) extends MyTrait[ Foo ]

trait MyTrait[ T ] { self : T =>
 T.bar
}

Изменение self: T на self: Foo, очевидно, работает, но MyTrait может расширить другой класс, который также имеет бар, поэтому self:Фу не приемлемо.

Я, наверное, ошибаюсь, есть идеи?

Ответы [ 2 ]

6 голосов
/ 24 февраля 2012

Я думаю, структурный тип - это то, что вам нужно:

trait MyTrait {
  self: { val bar: String } =>
 def showBar = bar
}

class Foo(val bar: String) extends MyTrait
1 голос
/ 24 февраля 2012

Уже работает.

scala> trait Foo[A] { self: A =>
     | }
defined trait Foo

scala> class Meh extends Foo[Meh]
defined class Meh

scala> class Duh extends Foo[Meh]
<console>:36: error: illegal inheritance;
 self-type Duh does not conform to Foo[Meh]'s selftype Foo[Meh] with Meh
       class Duh extends Foo[Meh]
                         ^

Редактировать:

Извините, я неправильно понял вопрос@ 4e6 верно.Вам нужен структурный тип.Небольшая вариация его решения:

scala> trait Foo[A <: { def bar: String }] { self: A =>
     | }
defined trait Foo

scala> class Bar extends Foo[Bar] {
     |   def bar = ""
     | }
defined class Bar

scala> class Baz extends Foo[Baz]
<console>:35: error: type arguments [Baz] do not conform to trait Foo's type parameter bounds [A <: AnyRef{def bar: Stri
ng}]
       class Baz extends Foo[Baz]
                         ^
...