Scala:用于早期定义/早期初始化/预初始化字段的示例

时间:2013-05-02 22:09:39

标签: scala traits

Scala允许您像这样进行早期定义:

trait A {
  val v: Int
}

class B extends { val v = 4 } with A

此功能的示例用法是什么?

3 个答案:

答案 0 :(得分:2)

每当该值用于特征初始化时。因此,对于这个特性的eaxmple:

trait UsefulTrait {
  val parameter : Int
  private val myHelperObject = new MyExpensiveClass(parameter)
}

该参数用于替换构造函数参数。但是,参数应该是一个抽象方法,因为它为实现者留下了更多的自由空间。

答案 1 :(得分:2)

让我们看一下 Scala中的编程一书(第451页)中的示例。如果我们有这样的定义:

trait RationalTrait {
   val numerArg: Int
   val denomArg: Int
}

然后numerArg和denomArg被称为抽象vals&特征可以直接使用而不需要扩展,如下所示:

val x = new RationalTrait {
   val numerArg = 1
   val denomArg = 2
}

val y = new {
   val numerArg = 1
   val denomArg = 1
} with RationalTrait

以上两个都是有效的预初始化的特征中的抽象val,除了,当你需要将表达式值放到抽象的val时,你只能使用后面的格式,如下所示:

val z = new {
  val numerArg = 1 * x
  val denomArg = 2 * x
} with RationalTrait

本书中另一个有趣的例子是类定义中的预初始化字段。

class RationalClass(n: Int, d: Int) extends {
  val numerArg = n
  val denomArg = d
} with RationalTrait {
  def + (that: RationalClass) = new RationalClass(
    numer * that.denom + that.numer * denom,
    denom * that.denom
  )
}

答案 2 :(得分:0)

特别是在单元测试中,您有兴趣单独测试特征。在这种情况下,您需要创建一个与您感兴趣的特征混合的对象。这是一个例子:

trait Display {
  def show(msg: String) = ...
}

val o = new Object with Display
o.show("hey!")

另一种情况是你的特质取决于注入的变量:

trait Logging {
  val stream: java.io.OutputStream
  def log(msg: String) = ...
}

val o = new { val stream = new FileOutputStream(...) } with Logging
o.log("hey!")