Scala, Расширить объект с помощью универсального признака

Я использую Scala и хочу расширить объект (одноэлементный) с помощью трейта, который предоставляет структуру данных и некоторые методы, например:

trait Tray[T] {
  val tray = ListBuffer.empty[T]

  def add[T] (t: T) = tray += t
  def get[T]: List[T] = tray.toList
}

А затем я хотел бы добавить трейт в объект, например:

object Test with Tray[Int]

Но есть несоответствия типов в add и get:

Test.add(1)
// ...

Как я могу заставить это работать? Или в чем моя ошибка?


person Themerius    schedule 24.12.2012    source источник


Ответы (1)


Проблема в том, что вы затеняет параметр типа признака с помощью T в методах add и get. См. Мой ответ здесь для получения более подробной информации о проблеме.

Вот правильный код:

trait Tray[T] {
  val tray = ListBuffer.empty[T]

  def add (t: T) = tray += t      // add[T] --> add
  def get: List[T] = tray.toList  // get[T] --> add
}

object Test extends Tray[Int]

Обратите внимание на использование extends в определении объекта - см. Раздел 5.4 спецификации для объяснения того, почему только with здесь не работает.

person Travis Brown    schedule 24.12.2012
comment
Хорошо спасибо. Я думаю, это потому, что scala внутренне дизассемблирует все объекты в функции, и это вызывает проблему с затенением! - person Themerius; 24.12.2012
comment
@Themerius: Я не уверен, что правильно понимаю, что вы имеете в виду, но проблема на самом деле довольно проста - вы можете ввести новое имя типа в список параметров типа метода, которое написано так же, как имя существующего типа вне метода. Вы можете делать то же самое на Java. - person Travis Brown; 24.12.2012
comment
Конечно, дело в размахе. Поэтому это скорее особенность. :) - person Themerius; 24.12.2012