2013-04-28 10 views
11

Trovo un certo uso confuso di tratto in qualche codice unit testing, come ad esempio:Come funzionano le parentesi graffe che seguono l'istanziazione dei tratti?

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

E poi istanziare il tratto utilizzando il nuovo e nel frattempo alcune espressioni avvolti da parentesi graffe hanno seguito la creazione di istanze.

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

Sono confuso da questa strana sintassi.

La mia domanda è:

  1. perché l'uso di follow tratto di un'istanza da parentesi graffe?

  2. qual è lo scopo dell'istanza dei tratti in questo caso e altri casi potrebbero anche essere utili?

+0

duplicato di http://stackoverflow.com/questions/12891321/why-are-traits-instantiable, http://stackoverflow.com/questions/6155570/what-does-it-mean-to-instantiate-a-trait – sourcedelica

risposta

22

Non si istanziano i tratti: i tratti da soli non possono essere istanziati; solo le classi non astratte possono. Quello che stai facendo qui sta usando la stenografia di Scala sia per la definizione di una classe anonima/anonima che estende la caratteristica e l'istanziazione nella stessa affermazione.

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

è l'equivalente di:

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

val namedClassMixingInTrait = new MyClass 

La differenza è che si può solo instaniate quella classe anonima, al momento della definizione in quanto non hanno un nome e non può avere argomenti del costruttore .

+0

Correzione - 'MyClass' non ha nulla a che fare con esso. – sourcedelica

6

Steve Buzzard ha già spiegato, quali sono le classi anonime, ma hai anche chiesto lo scopo. Lo scopo qui è che nei test spesso hai alcuni valori predefiniti che vuoi usare in ogni test. A volte hai anche lo stato, che può essere modificato da alcuni dei test. Per iniziare sempre con valori corretti (i test possono anche essere eseguiti in parallelo) è possibile incapsularli in queste istanze anonime. Il codice all'interno di questa istanza anonima è il costruttore, che verrà valutato all'istanziazione, quindi eseguendo i test.

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

è uguale

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

è uguale

val t = new Object with MyTrait { 
    val t1 = ... //some expression 
    val t2 = ... //some expression 
} 
Problemi correlati