Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does curly braces following trait instantiation work?

Tags:

scala

traits

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?

like image 528
xiaohan2012 Avatar asked Apr 28 '13 03:04

xiaohan2012


People also ask

Can traits be instantiated?

Unlike the other types, however, traits cannot be instantiated. Traits look about the same as any other type of class. However, like objects, they cannot take class parameters.

Can you instantiate a trait in Scala?

Unlike a class, Scala traits cannot be instantiated and have no arguments or parameters. However, you can inherit (extend) them using classes and objects.


2 Answers

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.

like image 62
Steve Buzzard Avatar answered Oct 21 '22 07:10

Steve Buzzard


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.

like image 21
drexin Avatar answered Oct 21 '22 07:10

drexin