简体   繁体   中英

Scala generics this.type

I'm trying to create a generic trait which has a method that returns an instance of the class itself. For example:

trait SomeGenericTrait[T]{
   def withData(newData : Seq[T]) : this.type
}

case class SomeImpl(data : Seq[Int]) extends SomeGenericTrait[Int] {
   override def withData(newData : Seq[Int]) : SomeImpl = copy(data = newData)
}

error: overriding method withData in trait SomeGenericTrait of type(newData: Seq[Int])SomeImpl.this.type; method withData has incompatible type

Without explicit return type:

case class SomeImpl(data : Seq[Int]) extends SomeGenericTrait[Int] {
   override def withData(newData : Seq[Int]) = copy(data = newData)
}

error: type mismatch;
 found   : SomeImpl
 required: SomeImpl.this.type

This fails compilation because the return value of the implemented withData is SomeImpl but the expected return type based on the trait's method declaration is SomeImpl.this.type .

Does anyone know how I need to change the return type of the trait method declaration so this will work? The more general use case I have is a way to expose a case class' copy method through a generic trait it extends. I know I may not be articulating this clearly, let me know if I should clarify anything.

Using Scala 2.10.0

You can solve it by parameterizing the trait with type type of class you're mixing into:

trait SomeGenericTrait[T, X] {
  def withData(newData: Seq[T]): X
}

case class SomeImpl(data: Seq[Int]) extends SomeGenericTrait[Int, SomeImpl] {
  override def withData(newData: Seq[Int]): SomeImpl = copy(data = newData)
}

this.type is a singleton type - the type of one specific instantiated SomeGenericTrait .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM