2013-04-28 45 views
11

我发现一些容易混淆的使用特性的一些单元测试代码,如:特征实例化后的大括号如何工作?

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

,然后使用新的,同时一些表达式被大括号包裹,随后实例化实例化特质。

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

我很困惑这种奇怪的语法。

我的问题是:

  1. 为什么使用如下特质被大括号实例?

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

+0

重复http://stackoverflow.com/questions/12891321/why-are-traits-instantiable, http://stackoverflow.com/questions/6155570/what-does-it-mean-to-instantiate-a-trait – sourcedelica 2013-04-29 14:56:43

回答

22

你没有实例化这些特征:特征本身不能被实例化;只有非抽象类可以。你在这里做的是用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 

不同的是,你只能在instaniate定义的时候,匿名类,因为它没有名字,它不能有构造函数的参数。

+0

更正 - “MyClass”与它无关。 – sourcedelica 2013-04-29 14:58:13

6

史蒂夫布扎德已经解释,什么是匿名类,但你也要求这个目的。这里的目的是,在测试中你经常有一些默认值,你想在每个测试中使用。有时你也有状态,这可能会被一些测试所改变。要始终以正确的值开始(测试也可以并行运行),可以将它们封装在这些匿名实例中。这个匿名实例中的代码是构造函数,将在实例化时进行评估,从而执行测试。

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