[英]Scala trait `this.type` in type parameter
看一下這兩個簡單的特征:
trait TreeNode1[S] {
def subNodes: List[S]
}
trait TreeNode2 {
def subNodes: List[this.type]
}
(並不是最好的命名方式,只是為了簡短起見,將其重命名。)
TreeNode1
定義一個具有其子級訪問權限的樹節點,指向其類型S
TreeNode2
定義了相同的對象,但其子對象與混合當前特征的類具有相同的類型(換句話說,具有統一子節點的樹節點)。
從理論上講TreeNode2
是一個特殊情況TreeNode1
:
trait TreeNode2 extends TreeNode1[this.type] {...}
但是Scala不會使用這種擴展來編譯TreeNode2
,因為不能以這種方式使用this.type
,盡管它在運行時的工作沒有任何矛盾。
我如何解決這種情況? 還是Scala不提供這種使用不良的機制?
我需要這種構造的原因如下:
我還有另一個需要混合TreeNode1
特性。我也有一些類將TreeNode1
與另一TreeNode1
類型混合在一起。 但是我也有幾個類具有相同的類型:
class SomeTreeNode extends TreeNode1[SomeTreeNode]
因此,如果我使用TreeNode2
,它將看起來更漂亮:
class SomeTreeNode extends TreeNode2
實現相同的邏輯。 但對於使用TreeNode2
應的情況下TreeNode1
,它實際上是,但斯卡拉不同意我的看法。
PS:至少,這是關於Scala的理論性問題,而不是廣泛的實際使用。
它的子代與當前特質混雜的班級具有相同的類型
不。這是一個常見的誤解。 this.type
是的單類型this
; 即只有兩個值是this
和null
。 TreeNode2
實例的所有子代都必須是同一實例。
要回答問題的另一部分,一個選擇是使S
成為類型成員,而不是類型參數:
trait TreeNode1 {
type S
def subNodes: List[S]
}
object TreeNode1 {
// use TreeNode1.Aux[S] where you had TreeNode1[S] originally
type Aux[T] = TreeNode1 { type S = T }
}
trait TreeNode2 {
type S = this.type // not really what you want
def subNodes: List[this.type]
}
(所謂的Aux
模式),但是這對您是否有效取決於它們的使用方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.