2013-04-28 4 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

ответ

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

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 
} 
Смежные вопросы