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

scala – 当超越一个特质,为什么这个价值是奇怪的?

发布时间:2020-12-16 19:05:17 所属栏目:安全 来源:网络整理
导读:演示 scala代码: trait A { val a = 3 val b = a + 2}trait B extends A { override val a = 10}object X extends Bprintln(X.b) 它打印值:2,为什么不是5或12? 解决方法 回答为什么: 写在Scala时 class A { val a = 2} 该值在类的构造函数中初始化(同样
演示 scala代码:

trait A {
  val a = 3
  val b = a + 2
}

trait B extends A {
  override val a = 10
}

object X extends B

println(X.b)

它打印值:2,为什么不是5或12?

解决方法

回答为什么:

写在Scala时

class A {
  val a = 2
}

该值在类的构造函数中初始化(同样的行为适用于特征和对象).此外,超类在子类之前初始化.这为您的用例导致以下行为:

B被创建(内存被保留),其中两个变量a和b的值为0.现在调用A的构造函数.因为a在子类中被覆盖,并且由于Scalas动态绑定性质,它不分配2,而是分配了子类的值.你想要成为10,但是由于此分配发生在B的构造函数(尚未被调用)中,所以分配默认值0.现在,b被分配.因为它不被覆盖,所以选择值a 2,其中a为0.因为A的构造函数在此完成,所以可以调用B的构造函数,它将10分配给a.

因此,a为10,b为2.

回答这个行为的错误:

只要您不能完全了解可能出现的问题,请勿使用阀门.使用defs或lazy vals而不是在类的构造函数中初始化值,因此可以轻易地覆盖.如果你绝对需要一个特征的val,那么做最后的

可以将var标记为独立于子类的初始化,可以使用var a:Type = _完成.这告诉编译器不要在定义类的构造函数中初始化此变量(但是意味着该值需要保持可变).它可以很容易地在子类中分配.当调用超类作为方法的构造函数时,这会很重要,初始化一个var:

class A {
  f()
  def f() = ()
}

class B extends A {
  // don't initialize this var with anything else here or
  // the later assignment will be overwritten
  var b: Int = _
  override def f() =
    b = 5
}

new B().b // prints 5

(编辑:李大同)

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

    推荐文章
      热点阅读