Scala类体中的右箭头

13

浏览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
好的,以下是您需要翻译的内容:问题:如何在Python中检测Ctrl和Shift键是否被按下?我正在编写一个Python程序,需要检测用户是否同时按下了Ctrl和Shift键。是否有一种方法可以检测这些键是否被按下?如果有,请给出一个示例代码。答案:您可以使用Pygame或wxPython等GUI库来检测按键事件。以下是一个使用Pygame的示例代码:import pygame pygame.init() screen = pygame.display.set_mode((400, 300)) while True: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: keys = pygame.key.get_pressed() if keys[pygame.K_LSHIFT] and keys[pygame.K_LCTRL]: print("Both Ctrl and Shift are pressed")在此示例中,我们创建了一个Pygame窗口并循环检查事件。当发生键盘按下事件时,我们使用pygame.key.get_pressed()方法获取当前按下的所有键,并检查两个特定的键是否都被按下。 - oluies
它们被命名为Self类型:请参见第27章“使用对象进行模块化编程”。 - oluies
可能是在Scala类定义开头使用=>的含义是什么?的重复问题。 - bummi
4个回答

9
第二版的Scala编程书在第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位于一个不同的trait中,因此超出了范围。
编译器不知道SimpleRecipes只与SimpleFoods混合使用。
然而,Scala提供了自身类型来解决这个问题。
技术上,自身类型是每当类内部提到this时假定的类型。
实际上,自身类型指定了混入该特质的任何具体类的要求
如果你有一个只能在混入另一个或多个特质时使用的特质,则可以指定应该假定那些其他特质。
在当前情况下,只需指定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引用失败的风险。

3
这是一个“self type”。请参阅《Programming in Scala Second Edition》的第29.4节。我认为第一版没有涉及到这个问题,而且我也没有一本可供查找。
在这个例子中,所有的操作都只是确保thisenum将引用Enumerationthis,无论它在Enumeration内部还是外部。

我在忙着整理我的相关摘录,没看到你的回答。+1 - VonC
+1 - 不过,你是不是想说“内部类”而不是“子类”? - Charles

2
这不是自类型注释,只是一个别名,代表了this,因为问题中没有涉及到类型要求,请查看这个SO问题

那个答案和链接很有用。再也没有任何疑问了。谢谢。 - Hartmut Pfarr

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一起使用。

至于您关于书籍的问题,您可以在《Programming in Scala Second Edition》的第29.4节中找到它。然而,请记住,书籍可能很快过时,所以您需要参考规范。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接