0

I have created a simple application with singleton object which contains local traits:

object Singleton {

  trait FirstTrait {
    val func1 = (i: Int) => i * 2
  }

  trait SecondTrait {
    val func2 = (s: String) => s
  }

  trait ThirdTrait {
    val func3 = () => println("Func 3")
  }
}

And now, in Main object, I would like to do something like this:

object Main extends App {    
  val singleton = Singleton.FirstTrait//cannot do this
}

But I cannot do this (compile error). Why? Why I have not an access into this local trait? If I change Singleton object into:

object Singleton {

  trait FirstTrait {
    val func1 = (i: Int) => i * 2
  }

  trait SecondTrait {
    val func2 = (s: String) => s
  }

  trait ThirdTrait {
    val func3 = () => println("Func 3")
  }

  object FirstObject extends FirstTrait {
    println(func1)
  }
}

Main works well and program compiles. But I call another singleton object from Singleton, not a trait. I understand that trait cannot be instanced, but I think it is not a solution for it, because I have also a simple ScalaTest test name, which looks like

"Singleton" should "test it" in Singleton.FirstTrait{...}

and here I have an access into FirstTrait. So why I cannot use it in normal code? I cannot understand it well. Maybe I am an idiot, but if someone could explain it to me well, I would be greatful.

2 Answers 2

5

It's a trait so you'll need to "instantiate" it properly:

val singleton = new Singleton.FirstTrait {}
// singleton: Singleton.FirstTrait = $anon$1@5e97da56

Note that technically a trait cannot be instantiated. The above expression is an instantiation of the anonymous class that extends the trait.

Sign up to request clarification or add additional context in comments.

4 Comments

Ok, I understand. So in Scala the trait can be instantiate like normal class? new keyword and object in one are not logical for me. Could you tell more?
That's right, and since it's a trait you'll need to implement its abstract members, if any. Here's a relevant link which might be of interest.
Not quite, this isn't instantiating the trait, but an anonymous class extending the trait.
@Alexey Romanov, good point. It's indeed an instantiation of the anonymous class that extends the trait.
1

Singleton.FirstTrait is a type, not a value. You can't write

val singleton = Singleton.FirstTrait

any more than you can write

val singleton = Int
val singleton = String

etc. Traits and classes can have companion objects (objects with the same name), but FirstTrait obviously doesn't have one.

You can use it as a type, e.g.

def foo(x: Singleton.FirstTrait) = {}
val x: Singleton.FirstTrait = new Singleton.FirstTrait {}

2 Comments

Ok, I got it. So in my second example I have an companion object for a trait so I can use it like a value.
It's just an object (not a companion object because it's called FirstObject, not FirstTrait), and you can use any object as a value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.