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

Scala用var替代了一个非抽象的def

发布时间:2020-12-16 09:21:35 所属栏目:安全 来源:网络整理
导读:在Scala我可以做到这一点: trait SomeTrait { protected def foo: String}class Wibble extends SomeTrait { protected var foo = "Hello"} 但是我不能做同样的事情,我为foo提供默认定义 trait SomeTrait { protected def foo: String = "World"}class Wibb
在Scala我可以做到这一点:

trait SomeTrait {
  protected def foo: String
}

class Wibble extends SomeTrait {
  protected var foo = "Hello"
}

但是我不能做同样的事情,我为foo提供默认定义

trait SomeTrait {
  protected def foo: String = "World"
}

class Wibble extends SomeTrait {
  protected var foo = "Hello" //complains about lack of override modifier

  override protected var foo = "Hello" //complains "method foo_ overrides nothing"
}

为什么我不能这样做?

编辑:在scala-users邮件列表上进行交谈后,我有raised this in trac

解决方法

在Scala中,当您编写一个var foo时,Scala编译器会自动为其生成一个setter(称为foo_ =)和一个getter(称为foo),并将该字段设置为private(如果您反编译一个具有javap的’public’Scala字段的类).这就是’foo_ =不覆盖任何东西’错误的方法.在你的特质中,你没有定义一个foo_ =方法,而对于一个public field setter和getter来说,它们总是成对的.

如果您不在trait(即抽象方法)中提供默认值,则不需要override关键字.因此,在第一个例子中,getter覆盖了抽象方法和setter …它只是在那里.编译器不会抱怨.但是,当您在trait中提供方法的实际实现时,您需要在覆盖时特别写入override关键字.当编写protected var foo时,您没有为getter指定override关键字,并且在写入覆盖保护的var foo时,还向编译器指出了要覆盖foo_ =的方法,但trait没有这样的方法.

另外,逻辑上你不能真正地用var覆盖def(考虑到一个严格的覆盖视图,像上一段). def在逻辑上是一个函数(你给它一些输入,它产生一个输出). var类似于no-arg函数,但也支持将其值设置为其他值,这是函数不支持的操作.相反,如果你把它改成val,那就行了.这就像一个总是产生相同(缓存)结果的函数.

如果你想对var有类似的行为,你可以这样做(通过使用显式的setter和getter):

class Wibble extends SomeTrait {
  private var bar = "Hello"
  override protected def foo = bar
  protected def foo_=(v: String) { bar = v}
}

现在你可以做任何事情你可以做一个var :).

val x = new Wibble
println(x.foo) // yields "Hello"
x.foo = "Hello again"
println(x.foo) // yields "Hello again"

(编辑:李大同)

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

    推荐文章
      热点阅读