How does curly braces following trait instantiatio

2019-04-03 23:50发布

问题:

I find some confusing use of trait in some unittesting code, such as:

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

And then instantiate the trait using new and meanwhile some expressions wrapped by curly braces followed the instantiation.

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

I am confused by this strange syntax.

My question is:

  1. why use follow trait instantiation by curly braces?

  2. what is the purpose of trait instantiation in this case and other cases might also be helpful?

回答1:

You are not instantiating the traits: traits by themselves cannot be instantiated; only non-abstract classes can. What you are doing here is using Scala's shorthand for both defining an anonymous/nameless class that extends the trait and instantiating it in the same statement.

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

Is the equivalent of:

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

val namedClassMixingInTrait = new MyClass

The difference is you can only instaniate that anonymous class at the time of definition since it doesn't have a name and it can't have constructor arguments.



回答2:

Steve Buzzard already explained, what anonymous classes are, but you also asked for the purpose. The purpose here is, that in tests you often have some default values, you want to use in every test. Sometimes you also have state, that may be changed by some of the tests. To always start with correct values (tests may also run in parallel) you can encapsulate them in these anonymous instances. The code inside this anonymous instance is the constructor, which will be evaluated at instantiation, thus executing your tests.



回答3:

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

is the same as

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

is the same as

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


标签: scala traits