Scala中类主体中的右箭头

时间:2011-02-12 20:21:07

标签: scala

浏览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编程”一书中找不到任何信息。

4 个答案:

答案 0 :(得分:7)

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为这种情况提供了自我类型   从技术上讲,无论何时在类中提及,自我类型都是假设的类型   实际上,一个自我类型指定了混合特征的任何具体类的要求   如果你有一个只在与另一个特征或特征混合时使用的特性,那么你可以指定应该假设其他特征。
  在目前的情况下,只需指定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)
}
  

鉴于新的自我类型,Pear现已可用   隐含地,对Pear的引用被认为是this.Pear   这是安全的,因为在SimpleRecipes中混合的任何具体类也必须是SimpleFoods的子类型,这意味着Pear将成为其成员。
  抽象的子类和特征不必遵循此限制,但由于它们无法使用new进行实例化,因此this.Pear引用不会失败

答案 1 :(得分:2)

这是自我类型。请参阅Scala第二版中的编程第29.4节。我不认为它在第一版中有所涉及,而且我无论如何也无法查找。

在这个示例中,所做的就是确保thisenumEnumeration的内部引用this的{​​{1}}。

答案 2 :(得分:1)

这不是自我类型注释,而只是的别名,因为问题中没有涉及类型要求,请查看此SO question

答案 3 :(得分:0)

它确实是自我类型注释。请参阅官方的Scala规范:

https://scala-lang.org/files/archive/spec/2.13/13-syntax-summary.html

根据此规范,其上下文无关的EBNF语法为:

SelfType    ::=  id [‘:’ Type] ‘=>’
                |  ‘this’ ‘:’ Type ‘=>’

因此,基本上,这意味着SelfType具有两种基本形式。在一种形式中,您可以使用带或不带Type的ID。另外,您可以使用this,但必须将其与Type一起使用。

关于本书的问题,可以在Scala Second Edition中的Programming的29.4节中找到。但是,请记住,书籍可能很快就会过时,因此您需要参考规范。