Конфликтующие вложенные наследованные черты

Предположим, что у меня есть следующий код:

trait Trait1 { 
  trait Inner {
    val name = "Inner1"
  }
}

trait Trait2 {
  trait Inner {
    val name = "Inner2"
  }
}

class Foo extends Trait1 with Trait2 {
  // I want Concrete1 to be a Trait1.Inner not a Trait2.Inner
  class Concrete1 extends Inner
  val c = new Concrete1
}

object Obj {
  def main(args: Array[String]): Unit = {
    val foo = new Foo
    println(foo.c.name)
  }
}

Когда я смешиваюсь в Trait1 и Trait2, обращение к Inner кажется, принимает значение по умолчанию к Inner тип какой бы ни черта я смешивающийся второй; таким образом, когда я звоню Obj main метод это печатает Inner2. Как я могу обратиться к Trait1.Inner в Foo? Все три из следующего дают ошибки компилятора:

class Concrete1 extends Trait1.Inner
class Concrete1 extends Trait1$Inner
class Concrete1 extends Trait1#Inner
7
задан ams 15 January 2010 в 17:07
поделиться

4 ответа

Вместо

class Concrete1 extends Inner

используют это

class Concrete1 extends super[Trait1].Inner

, что должно получить то, что вы хотите

6
ответ дан 6 December 2019 в 14:04
поделиться

В качестве альтернативы, Вы также можете попробовать StartSwarm. Я взял его и запустил, используя QUnit, чтобы запустить мои тесты JS.

-121--963343-

Тег < br > будет вставлен после конца каждого элемента < a >... :

from BeautifulSoup import BeautifulSoup, Tag

# ....

soup = BeautifulSoup(data)
for a in soup.findAll('a'):
    a.parent.insert(a.parent.index(a)+1, Tag(soup, 'br'))

Вы не можете использовать soup.findAll (tag = '') , поскольку


Если вы хотите поместить элементы < a > в элемент < p > по запросу в комментарии, вы можете использовать следующее:

for a in soup.findAll('a'):
    p = Tag(soup, 'p') #create a P element
    a.replaceWith(p)   #Put it where the A element is
    p.insert(0, a)     #put the A element inside the P (between <p> and </p>)

Опять же, вы не создаете элементы < p > и

отдельно, потому что они являются частью одного и того же.

-121--3250477-

В шаблоне имеются два пространства имен (шаблон является телом класса, объекта или признака.)

  1. Члены: значения, значения, параметры и вложенные объекты
  2. Типы: псевдонимы типов, вложенные признаки и вложенные классы

При наследовании из нескольких родительских шаблонов конфликты в этих пространствах имен разрешаются посредством класса linases

Вы можете изменить порядок наследования, чтобы ввести в свой класс нужного родителя Inner, или найти альтернативный дизайн.

4
ответ дан 6 December 2019 в 14:04
поделиться

Один вариант (если вы можете быть инвазивными К чертам) состоит в том, чтобы определить каждую внутреннюю черту как член типа, который имеет неконфудирующее имя.

trait Trait1 {
  type Inner1 = Inner
  trait Inner {
    val name = "Inner1"
  }
}

trait Trait2 {
  type Inner2 = Inner
  trait Inner {
    val name = "Inner2"
  }
}

class Foo extends Trait1 with Trait2 {
  class Concrete1 extends Inner1
  class Concrete2 extends Inner2
  val c1 = new Concrete1
  val c2 = new Concrete2
}

object App extends Application {
  val foo = new Foo
  println(foo.c1.name) // Inner1
  println(foo.c2.name) // Inner2
}

Если вы не можете быть инвазивными для оригинальных черт (Trait1 и Trait2), вы можете расширить их для определения элемента типа.

trait Trait1 {
  trait Inner {
    val name = "Inner1"
  }
}
trait Trait2 {
  trait Inner {
    val name = "Inner2"
  }
}

trait Trait1a extends Trait1 {
  type Inner1 = Inner
}
trait Trait2a extends Trait2 {
  type Inner2 = Inner
}

class Foo extends Trait1a with Trait2a {
  class Concrete1 extends Inner1
  class Concrete2 extends Inner2
  val c1 = new Concrete1
  val c2 = new Concrete2
}

Другой подход будет использовать промежуточную черту для определения вашего первого конкретного класса:

trait Trait1 {
  trait Inner {
    val name = "Inner1"
  }
}
trait Trait2 {
  trait Inner {
    val name = "Inner2"
  }
}

trait FooIntermediate extends Trait1 {
  class Concrete1 extends Inner
}

class Foo extends FooIntermediate with Trait2 {
  class Concrete2 extends Inner
  val c1 = new Concrete1
  val c2 = new Concrete2
}
3
ответ дан 6 December 2019 в 14:04
поделиться

Почему бы не заказать черт в том порядке, чтобы вы ожидаете их иметь приоритет? Линеаризация чертов не является произвольным, но указана.

2
ответ дан 6 December 2019 в 14:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: