Scala: Example use for early definition / early in

2019-07-04 04:18发布

问题:

Scala allows you to make early definitions like so:

trait A {
  val v: Int
}

class B extends { val v = 4 } with A

What is an example use of this feature?

回答1:

Whenever the value is used for the trait initialization. So for eaxmple for this trait:

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

The parameter is used to substitute for a constructor parameter. However the parameter should be rather made an abstract method, because it leaves more free space to the implementer.



回答2:

Let's see a example from the Programming in Scala book (page 451). If we have a definition like this:

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

Then numerArg and denomArg are called abstract vals & the trait can be used directly without extends, like this:

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

Or

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

The above two are both valid Pre-initializing of abstract val in trait, except that when you need to put an expression value to abstract vals, you can only use the later form, like this:

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

Another interesting example in book is to Pre-initialized fields in a class definition.

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
  )
}


回答3:

In unit tests in particular, you are interested on testing traits in isolation. In this case, you need to create an Object mixed in with the trait you are interested. This is an example:

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

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

Another scenario is when your trait depends on injected variables:

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

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


标签: scala traits