Существует ли “САМ” тип в scala, который представляет текущий тип?

Если Ваш SQL Server использования, 2005 и выше Вас может создать снимок базы данных, который позволит Вам откатывать любые изменения, внесенные в момент времени снимка.

13
задан James Black 19 October 2009 в 03:34
поделиться

3 ответа

Я не уверен, будет ли это действительно полезно для вас, но самое близкое, что я могу придумать, - это this.type . Например:

scala> class A { val l: List[this.type] = Nil }  
defined class A

scala> new A().l
res3: List[A] = List()

scala> class B extends A
defined class B

scala> new B().l
res4: List[B] = List()
8
ответ дан 1 December 2019 в 21:12
поделиться

Ключевое слово this в Scala более или менее эквивалентно.

При разработке расширяемого программного обеспечения иногда бывает удобно объявить тип значения this явно:

Явно типизированные ссылки на себя в Scala
http://www.scala-lang.org/node/124

2
ответ дан 1 December 2019 в 21:12
поделиться

Типы однокнопочных и ETSR не решают проблему. Я сам искал такую же возможность в Scala, но, видимо, в ней отсутствует так называемая аннотация самотипа.

Есть обстоятельства, при которых такие самотипные аннотации могли бы быть очень полезны. Рассмотрим пример (адаптированный из Circular type parameters question example):

// we want a container that can store elements
trait Container[E <: Element[E]] {
  def elements: Seq[E]
  def add(elem: E): Unit
}

// we want elements be aware of their enclosing container
trait Element[E <: Element[E]] {
  def container: Container[E]
}

Предположим, вы поместили его в библиотеку. Потребитель библиотеки должен сделать следующее:

object PersonContainer extends Container[Person] {
  // actual implementation is not important
  def elements = Nil
  def add(p: Person) = {}
}

class Person extends Element[Person] {             // {1}
  def container = PersonContainer
}

Все в порядке и все работает так, как и ожидалось. Единственное, что касается потребителя библиотеки, это то, что supposed должен использовать параметр типа self-bound (#1 в коде). Но это еще не все. Теперь предположим, что вы имеете в виду какой-то паттерн ActiveRecord и хотите добавить метод save к Element, который просто делегирует ему метод контейнера add. Удивительно, но это не так просто:

trait Element[E <: Element[E]] {
  def container: Container[E]
  def save() = container.add(this)   // won't compile
}

found   : Element[E]
required: E

Интуитивно, у нас есть несколько вариантов:

  • заставить добавить метод принять Element[E] вместо E;
  • проставить этот в Element[E].

Ни один из этих вариантов не является удовлетворительным только потому, что E не совпадает с Element[E] (реализации не принуждают использовать параметры типа self-bound). Единственное, что я вижу в решении этой проблемы - это наличие концепции типа self-type в Scala (допустим, она есть в нашем любимом языке):

trait Container[E <: Element] {
  def elements: Seq[E]
  def add(elem: E): Unit
}

trait Element {  // the type parameter would be redundant ...
  def save() = container.add(this)  // ... and this would be possible, too, ...
  def container: Container[this]  // ... if only we could do this
}

Если бы компилятор мог трактовать this (или, может быть, другое ключевое слово), когда он используется внутри квадратных скобок, как тип действительной реализации (т.е. как тип в результате obj.getClass), то проблемы исчезли бы.

P.S. Может ли кто-нибудь подумать о включении этого материала в список желаний Scala? К сожалению, я не знаю, как сложно реализовать такую логику, так как могут возникнуть проблемы с пресловутым стиранием JVM.

P.P.S. Или, может быть, есть другой Scala-путь, о котором я не знаю?

2
ответ дан 1 December 2019 в 21:12
поделиться
Другие вопросы по тегам:

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