浏览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 ...
}
Run Code Online (Sandbox Code Playgroud)
有什么thisenum =>用?我在"Scala编程"一书中找不到任何信息.
Scala 2d编程中的编程在第29.4节"将模块拆分为特征"一节中介绍了自我类型的概念:
SimpleFoods特征可能看起来像:
trait SimpleFoods {
object Pear extends Food("Pear")
def allFoods = List(Apple, Pear)
def allCategories = Nil
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一直很好,但不幸的是,如果你试图定义一个像这样的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)
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是与
Pear使用它的特性不同,因此它超出了范围.
编译器不知道SimpleRecipes只与它混合在一起SimpleFoods.
但是,有一种方法可以告诉编译器.Scala为这种情况提供了自我类型.
从技术上讲,无论何时在类中提到,自我类型都是假定的类型.
实际上,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)
}
Run Code Online (Sandbox Code Playgroud)
鉴于新的自我类型,
Pear现在可用.
隐含地,引用Pear被认为是this.Pear.
这是安全的,因为混入的任何具体类SimpleRecipes也必须是子类型SimpleFoods,这意味着Pear它将是一个成员.
抽象的子类和特征不必遵循此限制,但由于它们无法使用new进行实例化,因此不存在this.Pear引用失败的风险
这是一种自我类型。请参阅《Scala 编程》第二版第 29.4 节。我认为第一版中没有涉及到它,而且我也没有可以查找的内容。
在这个例子中,所做的就是确保从 的任何内部thisenum引用Enumeration's 。thisEnumeration
| 归档时间: |
|
| 查看次数: |
1664 次 |
| 最近记录: |