2013-04-28 47 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 
}