当前位置: 首页 > 知识库问答 >
问题:

何时在Scala特征中使用val或def?

党佐
2023-03-14

我浏览了有效的scala幻灯片,在幻灯片10中提到,不要在抽象成员的特征中使用val,而是使用def。幻灯片没有详细提到为什么在trait中使用抽象val是反模式。如果有人能解释在抽象方法的特征中使用val vs def的最佳实践,我将不胜感激

共有1个答案

漆雕和雅
2023-03-14

def可以通过defval惰性val对象实现。所以它是定义成员的最抽象的形式。因为traits通常是抽象接口,所以说你想要一个val就是说实现应该怎么做。如果要求val,则实现类不能使用def

只有当您需要稳定的标识符时,例如依赖路径的类型,才需要val。那是你通常不需要的东西。

比较:

trait Foo { def bar: Int }

object F1 extends Foo { def bar = util.Random.nextInt(33) } // ok

class F2(val bar: Int) extends Foo // ok

object F3 extends Foo {
  lazy val bar = { // ok
    Thread.sleep(5000)  // really heavy number crunching
    42
  }
}
trait Foo { val bar: Int }
trait Foo { 
  val bar: Int 
  val schoko = bar + bar
}

object Fail extends Foo {
  val bar = 33
}

Fail.schoko  // zero!!

Edit(Jan,2016年):允许使用惰性val实现重写抽象的val声明,这样也可以防止初始化失败。

 类似资料:
  • 主要内容:实例,实例,特征构造顺序Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。 与接口不同的是,它还可以定义属性和方法的实现。 一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。 Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示: 实例 trait Equal {   def isEq

  • Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。 与接口不同的是,它还可以定义属性和方法的实现。 一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。 Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示: trait Equal { def isEqua

  • 在这种情况下我们必须使用val而不是var?我知道val是当我们知道值不会改变的时候。但我的印象是var对所有情况都是好的。是真的吗?换句话说:只用var有问题吗?

  • 问题内容: Java中的以下代码可正确编译: 而Scala中的此代码不: Java代码清单到Scala的正确翻译(如果存在)是什么? 欢迎对语言设计进行理论解释。 问题答案: 内部类型仅针对特征的特定实例实现定义。由于scala具有 依赖于路径的 类型,因此的每个实例将具有自己的子特性。 如果您需要一个接口来实现客户端的一般行为,并且不依赖于特定实例,则应在

  • 我定义了一个通用的环境特征: 为此,我提供了以下实现: 此外,我定义了一个通用事件特征,该特征具有一个接受通用环境作为参数的方法: 对于这个事件特征,我提供了以下实现,其中exec()方法接受MyEnvironment类型的参数,使我能够访问MyEnvironment的特定值。 然而,Scala编译器输出了一个错误,从中可以看出MyEnvironment似乎没有被识别为环境[整数]: 错误:方法e

  • 问题内容: 我用作以下功能选择器。 我还执行以下操作,以调整以下超参数。 但是,我不清楚如何将特征选择()与合并。 编辑: 当我运行@Gambit建议的答案时,出现以下错误: 我可以通过在参数列表中使用来解决上述问题。 我现在的问题是 如何使用所选的特征和参数来验证模型是否可以很好地处理看不见的数据。如何获得并使用进行训练? 如果需要,我很乐意提供更多详细信息。 问题答案: 基本上,您希望在选择特