加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala中类主体中的右箭头

发布时间:2020-12-16 18:52: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
浏览 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编程”一书中找不到任何信息.

解决方法

Scala 2d编程中的编程在第29.4节“将模块拆分为特征”一节中介绍了自我类型的概念:

The SimpleFoods trait could look as:

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

So far so good,but unfortunately,a problem arises if you try to define a SimpleRecipes trait like this:

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

The problem here is that Pear is located in a different trait from the one that
uses it,so it is out of scope.
The compiler has no idea that SimpleRecipes is only ever mixed together with SimpleFoods.
There is a way you can tell this to the compiler,however. Scala provides the self type for precisely this situation.
Technically,a self type is an assumed type for this whenever this is mentioned within the class.
Pragmatically,a self type specifies the requirements on any concrete class the trait is mixed into.
If you have a trait that is only ever used when mixed in with another trait or traits,then you can specify that those other traits should be assumed.
In the present case,it is enough to specify a self type of SimpleFoods,as shown:

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

Given the new self type,Pear is now available.
Implicitly,the reference to Pear is thought of as this.Pear.
This is safe,because any concrete class that mixes in SimpleRecipes must also be a subtype of SimpleFoods,which means that Pear will be a member.
Abstract subclasses and traits do not have to follow this restriction,but since they cannot be instantiated with new,there is no risk that the this.Pear reference will fail

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读