2013-11-23 154 views
11

我想創建一個通用特質,它有一個方法返回類本身的一個實例。例如:斯卡拉泛型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 

沒有明確的返回類型:

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 

這失敗編譯因爲實施withData的返回值是SomeImpl但是基於特徵的方法聲明中的預期收益類型爲SomeImpl.this.type

有誰知道我需要如何更改特徵方法聲明的返回類型,所以這將工作?我使用的更一般的用例是通過它擴展的通用特徵公開案例類'copy方法。我知道我可能沒有清楚地說清楚,讓我知道我是否應該澄清任何事情。

使用Scala的2.10.0

回答

10

您可以通過參數化與類類型型性狀解決它,你會混入到:

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是一個單獨的類型 - 一個特定的類型實例化SomeGenericTrait

+1

(這種模式被稱爲[CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#In_other_languages)) – Rich

+0

換句話說,'this.type'只允許返回'this',但是不允許返回由'copy'創建的同一類的新實例。 –

+0

稍微嚴格的聲明應該是特徵SomeGenericTrait [T,+ X <:SomeGenericTrait [T,X]],它將X限制爲特徵的子類。 –