簡體   English   中英

類型參數中的Scala特征`this.type`

[英]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 ; 只有兩個值是thisnull 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM