我在某些单元测试代码中发现了一些令人困惑的特性使用,例如:
trait MyTrait {
val t1 = ... //some expression
val t2 = ... //some expression
}
然后使用new实例化特征,同时在实例化之后用花括号包裹一些表达式。
test("it is a test") {
new MyTrait {
// do something with t1 and t2
}
}
我对这种奇怪的语法感到困惑。
我的问题是:
为什么要使用花括号跟踪特征实例?
在这种情况下特质实例化的目的是什么,其他情况也可能有帮助?
答案 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
}