2013-11-23 21 views
11

Sınıfın bir örneğini döndüren bir yönteme sahip genel bir özellik oluşturmaya çalışıyorum. açık dönüş türü olmadanScala genericics this.type

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 

: Örneğin uygulanan withData dönüş değeri SomeImpl ama özellik yöntemi bildiriminde dayalı olarak beklenen getiri tipi SomeImpl.this.type çünkü

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 

Bu derleme başarısız olur.

Özellik yöntemi bildiriminin dönüş türünü nasıl değiştirmem gerektiğini bilen var mı? Bu işlem işe yarayacak mı? Daha genel kullanım durumum, 'copy yönteminin genişlediği genel bir özellik aracılığıyla bir vaka sınıfını ortaya çıkarmanın bir yoludur. Bunu açıkça ifade edemeyeceğimi biliyorum, bir şeyi açıklığa kavuşturmalıysam bana bildirin. - Belirli birinin tip

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 bir tekil türüdür: Scala 2.10.0

cevap

10

kullanma

Sen içine karıştırma olduğunuz sınıfın tipi türü ile özellik parameterizing bunu çözebilir örneklenmiş SomeGenericTrait.

+1

(Bu kalıp [CRTP] olarak bilinir (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#In_other_languages)) – Rich

+0

Başka bir deyişle, 'this.type' yalnızca 'this' döndürmeyi sağlar, ancak yapar 'copy' tarafından oluşturulan aynı sınıfın yeni bir örneğini döndürmesine izin vermeyin. –

+0

Biraz daha katı beyanname, özelliğin alt sınıflarına X'i sınırlayan bir özellik olan SomeGenericTrait [T, + X <: SomeGenericTrait [T, X]] olacaktır. –