在Scala的类体中的右箭头
在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: _*) /* 请注意,`readResolve`不能是private,否则JVM在反序列化子类时不会调用它。 */ protected def readResolve(): AnyRef = thisenum.getClass.getField("MODULE$").get() // ... SNIP ... }
thisenum =>
是干什么用的?在《Scala编程》这本书中找不到任何相关信息。
在Scala中,类体中的箭头(Right arrow in class body)不是一个自身类型注解,而只是一个对this的别名,因为问题中没有涉及类型要求。通过查阅这个Stack Overflow问题的回答和链接,可以解决这个问题。没有任何更多的疑问了,谢谢。
原因:箭头(Right arrow in class body)在类体中的使用并不是一个自身类型注解,而只是对this的别名。
解决方法:通过查阅这个Stack Overflow问题的回答和链接,可以得到解决方法。
在Scala编程的第二版中,介绍了在第29.4节"将模块拆分为特质"中引入了自身类型的概念。
这里有两个特质,一个是SimpleFoods,另一个是SimpleRecipes。SimpleFoods中定义了一个Pear对象,然后定义了allFoods和allCategories方法。SimpleRecipes中定义了一个FruitSalad对象,它的成员包括一个名称、一个食物列表和一个描述。然后定义了一个allRecipes方法。
问题出在SimpleRecipes中的FruitSalad对象的食物列表中引用了SimpleFoods中的Pear对象。这是因为Pear对象位于不同的特质中,所以它超出了范围。编译器并不知道SimpleRecipes只会和SimpleFoods一起使用。为了解决这个问题,Scala提供了自身类型的语法。
自身类型是指在类中使用this时,假定的类型。它实际上指定了对混入该特质的任何具体类的要求。如果有一个特质只有在与另一个特质混入时才会使用,那么可以指定这些其他特质应该被假定。在这种情况下,只需要指定SimpleFoods作为自身类型。
通过引入自身类型,Pear对象现在是可用的。隐式地,对Pear的引用被认为是this.Pear。这是安全的,因为混入SimpleRecipes的任何具体类也必须是SimpleFoods的子类型,这意味着Pear将是一个成员。抽象子类和特质不必遵循这个限制,但由于它们不能用new实例化,所以不存在this.Pear引用失败的风险。
最终,通过指定自身类型,问题得到了解决。