Стрелка вправо в теле класса в Scala - PullRequest
6 голосов
/ 12 февраля 2011

Просматривая исходный код Scala, я наткнулся на Enumeration.scala:

abstract class Enumeration(initial: Int, names: String*) extends Serializable {
  thisenum =>

  def this() = this(0)
  def this(names: String*) = this(0, names: _*)    

  /* Note that `readResolve` cannot be private, since otherwise
     the JVM does not invoke it when deserializing subclasses. */
  protected def readResolve(): AnyRef = thisenum.getClass.getField("MODULE$").get()

  // ... SNIP ...

}

Для чего нужен thisenum =>?Я не смог найти никакой информации в книге "Программирование в Scala".

Ответы [ 3 ]

7 голосов
/ 13 февраля 2011

В издании «Программирование в Scala 2d» концепция самостоятельного типа представлена ​​в разделе 29.4 «Разделение модулей на черты»:

Черта SimpleFoods может выглядеть следующим образом:

trait SimpleFoods {
  object Pear extends Food("Pear")
  def allFoods = List(Apple, Pear)
  def allCategories = Nil
}

Пока все хорошо, но, к сожалению, проблема возникает, если вы пытаетесь определить черту SimpleRecipes следующим образом:

trait SimpleRecipes { // Does not compile
  object FruitSalad extends Recipe(
    "fruit salad",
    List(Apple, Pear), // Uh oh
    "Mix it all together."
  )
  def allRecipes = List(FruitSalad)
}

Проблема в том, что Pear находится в отличительной черте от той, которая его использует, поэтому она выходит за рамки.
Компилятор не знает, что SimpleRecipes когда-либо смешивается только с SimpleFoods.
Существуетоднако вы можете сообщить об этом компилятору.Scala предоставляет тип self именно для этой ситуации.
Технически тип self является предполагаемым типом для этого всякий раз, когда он упоминается в классе .
Прагматически, , который указывает тип selfтребования к любому конкретному классу, к которому эта черта примешивается .
Если у вас есть черта, которая используется только когда смешана с другой чертой или чертами, вы можете указать, что эти другие черты должны быть приняты.
В данном случае достаточно указать собственный тип SimpleFoods, как показано:

trait SimpleRecipes {
  this: SimpleFoods =>
  object FruitSalad extends Recipe(
    "fruit salad",
    List(Apple, Pear), // Now Pear is in scope
    "Mix it all together."
  )
  def allRecipes = List(FruitSalad)
}

С учетом нового типа self, Pear теперь доступно.
Неявно, ссылка на Pear считается this.Pear.
Это безопасно, потому что любой конкретный класс, который смешивается в SimpleRecipes, также должен быть подтипом SimpleFoods, что означает, чтоPear будет членом.
Абстрактные подклассы и признаки не должны следовать этому ограничению, но, поскольку они не могут быть созданы с новым, нет риска, что ссылка this.Pear будетЯ терплю неудачу

2 голосов
/ 13 февраля 2011

Это тип . См. Раздел 29.4 «Программирование в Scala Second Edition». Я не думаю, что это было описано в первом издании, и у меня все равно нет места для поиска.

В этом примере все, что было сделано, это удостоверилось, что thisenum будет ссылаться на Enumeration this из любой внутренней части Enumeration.

1 голос
/ 16 января 2016

Это не аннотация собственного типа, а псевдоним для этого , поскольку в вопросе нет требований к типу, проверьте этот SO вопрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...