2017-01-17 124 views
1

所以我遇到了一些麻煩,我認爲這是特質實現中非常簡單的情況,我希望有一些簡單的解決方案,我錯過了。我想對接受作爲參數的性狀的方法(返回爲只值的具體實施,它被稱爲上的具體類型。斯卡拉限制實施類型的特質方法

trait Foo { 
    type ConcreteFoo // what to put here? 
    def combine(that:ConcreteFoo):ConcreteFoo 
} 

class FooImpl1 extends Foo { 
    def combine(that:FooImpl1):FooImpl1 = { 
    // implementation 
    } 
} 

class FooImpl2 extends Foo { 
    def combine(that:FooImpl2):FooImpl2 = { 
    // implementation 
    } 
} 

現在我有一個type Self = FooImpl的實現類,但我寧願有可能的話是需要照顧它的特​​點的東西

+0

該解決方案被稱爲'f-bound polymorphism'。在這裏閱讀:https://twitter.github.io/scala_school/advanced-types.html#fbounded – maasg

回答

1

這正是F-Bounded Polymorphism:

trait Foo[T <: Foo[T]] 
    def combine(that: T): T 
} 

class FooImpl1 extends Foo[FooImpl1] { 
    def combine(that: FooImpl1): FooImpl1 = { 
    ??? 
    } 
} 

class FooImpl2 extends Foo[FooImpl2] { 
    def combine(that: FooImpl2): FooImpl2 = { 
    ??? 
    } 
} 
+0

完美!我記得爲什麼我最初沒有采取這種方法。 'Foo'實際上也需要類型參數,所以當我不想被限制到一個具體的'Foo'實現時,我不知道如何在不增加類型參數的情況下這樣做。即。特質Foo [A,F <:Foo [A,F]]; def accumulate(f:Foo [A,_])'失敗,因爲'_'不滿足綁定,但我看不到如何填充它。 –

+0

@John你可以做'def accumulate(f:F)',因爲它已經被特質聲明所約束了。 –

+0

對不起,我不清楚這段代碼。 '累積'沒有在'Foo'上定義,而是在其他地方爲泛型'Foo'定義。所以實際上可以想象像'def accumulate [A](f:Foo [A,_])''。我知道我可以做'積累[A,F':Foo [A,F]](f:F)',但這正是我想避免的類型參數的擴散。在這種情況下,是否有任何爲什麼要提供帶有適當邊界的擦除類型參數?顯然,天真的方法給了無限的迴歸:'def accumulate [A](f:Foo [A,_ <:Foo [A,_ <:Foo [A,_ ...]]) –

0

您可以將類型參數添加到您的特點是這樣的:

trait Foo[A] { 
    def combine(that: A): A 
} 

class FooImpl1 extends Foo[FooImpl1] { 
    override def combine(that: FooImpl1): FooImpl1 = ??? 
} 

class FooImpl2 extends Foo[FooImpl2] { 
    override def combine(that: FooImpl2): FooImpl2 = ??? 
}