7

I'm using Scala and I want to extend a (singleton) object with a trait, which delivers a data structure and some methods, like this:

trait Tray[T] {
  val tray = ListBuffer.empty[T]

  def add[T] (t: T) = tray += t
  def get[T]: List[T] = tray.toList
}

And then I'll would like to mix-in the trait into an object, like this:

object Test with Tray[Int]

But there are type mismatches in add and get:

Test.add(1)
// ...

How can I'll get this to work? Or what is my mistake?

1 Answer 1

23

The problem is that you're shadowing the trait's type parameter with the T on the add and get methods. See my answer here for more detail about the problem.

Here's the correct code:

trait Tray[T] {
  val tray = ListBuffer.empty[T]

  def add (t: T) = tray += t      // add[T] --> add
  def get: List[T] = tray.toList  // get[T] --> add
}

object Test extends Tray[Int]

Note the use of extends in the object definition—see section 5.4 of the spec for an explanation of why with alone doesn't work here.

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

3 Comments

Okay, thanks. I'll think it's because scala disassemble internal all objects to functions, and this causes this shadowing problem!
@Themerius: I'm not sure I understand exactly what you mean, but the problem's actually pretty simple—you can introduce a new type name in a method's type parameter list that's spelled the same as an existing type name outside of the method. You can do exactly the same thing in Java.
Sure, it's a scope thing. Therefore it's more a feature. :)

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.