特征实例化后的花括号如何工作?

时间:2013-04-28 03:07:20

标签: scala traits

我在某些单元测试代码中发现了一些令人困惑的特性使用,例如:

trait MyTrait {
  val t1 = ... //some expression
  val t2 = ... //some expression
}

然后使用new实例化特征,同时在实例化之后用花括号包裹一些表达式。

test("it is a test") {
  new MyTrait {
    // do something with t1 and t2
  }
}

我对这种奇怪的语法感到困惑。

我的问题是:

  1. 为什么要使用花括号跟踪特征实例?

  2. 在这种情况下特质实例化的目的是什么,其他情况也可能有帮助?

3 个答案:

答案 0 :(得分:33)

您没有实例化特征:特征本身无法实例化;只有非抽象类才可以。你在这里做的是使用Scala的简写来定义一个匿名/无名的类,它扩展了特征并在同一个语句中实例化它。

val anonClassMixingInTrait = new MyTrait {
  def aFunctionInMyClass = "I'm a func in an anonymous class"
}

相当于:

class MyClass extends MyTrait {
  def aFunctionInMyClass = "I'm a func in a named class"
}

val namedClassMixingInTrait = new MyClass

不同之处在于,您只能在定义时实例化匿名类,因为它没有名称且不能有构造函数参数。

答案 1 :(得分:8)

Steve Buzzard已经解释过,匿名课程是什么,但你也问过这个目的。这里的目的是,在测试中,您经常有一些默认值,您希望在每个测试中使用。有时你也有状态,可能会被一些测试改变。要始终以正确的值开始(测试也可以并行运行),您可以将它们封装在这些匿名实例中。这个匿名实例中的代码是构造函数,它将在实例化时进行评估,从而执行测试。

答案 2 :(得分:4)

val t = new MyTrait {
  val t1 = ... //some expression
  val t2 = ... //some expression
}

相同
val t = new AnyRef with MyTrait {
  val t1 = ... //some expression
  val t2 = ... //some expression
}

相同
val t = new Object with MyTrait {
  val t1 = ... //some expression
  val t2 = ... //some expression
}