這將是不合適的。這是爲什麼,用一個簡單的例子。我們不需要兩個通用參數,我們不需要亞型TI,TJ和TK要麼
trait TA[X <: TA[X]]
trait TC[X <: TA[X]]
class Z extends TC[TA[_]]
類型參數[TA [_]不符合特質TC的類型參數 界[X < :TA [X]]
讓我們來看看爲什麼這個聲明是不健全的,它是正確的,它失敗了。 讓我們添加一些代碼。我將TC
更改爲class
,以便代碼可以轉換爲java。 A trait
也可以在scala中使用。
trait TA[X <: TA[X]] {def f(x: X) }
class TC[X <: TA[X]] {def g(x: X) = x.f(x)}
它工作正常,x: X
也TA[X]
,所以它有一個例行f
,將接受一個X
。
如果我們試圖代替
class TC2[X <: TA[_]] {def g(x: X) = x.f(x)}
那麼它失敗。我們知道在x
上有一個f
方法,但我們不知道需要什麼類型作爲參數,我們不知道x
會沒事。事實上,假如我們定義
class T1 extends TA[T1]] {def f(t1: T1) = {}; def t1Only = println("only in T1")}
class T2 extends TA[T1]] {def f(t1: T1) = t1.t1Only }
現在,如果TC2
是允許的,我可以創造一個TC2[T2]
,叫g
與T2
,它會叫f
在T2
與T2
。這是不允許的,正確的如T2
沒有方法t1Only
。
這顯示了爲什麼TC
不能接受TA[_]]
作爲其參數,因爲這將允許T2
,這與方法g
不兼容。所以我們爲什麼不能用參數TA[_]
來定義Z
。這將是完全相同的Java,並與您的原始代碼以及。
編輯:我覺得有點內疚,我的答案。由於我給出了爲什麼不應該被允許的原因,我認爲會有一個簡單的解決方法。它失敗了,我沒有時間進一步調查,並張貼沒有提及它。解決方法是一種自我類型。如果我們這樣做
trait TA[X <: TA[X]] {self: X => }
那麼我們就不能定義T2 extends TA[T1]
。所以它原來的代碼更有限。但是我們必須接受原始代碼的限制,因爲它是不健全的。所以它不能只是一個語法技巧,它必須讓事情變得不可能,而不是。我認爲T2 extends TA[T1]
可能不是有意的東西,而且這是防止的一件事。
顯然,它不是,同樣的錯誤。現在我沒有一個例子說明它不應該起作用。當然這並不意味着沒有。
然後,我看看邁爾的解決方案,想知道爲什麼T2 extends TA[T1]
的可能性不會傷害它。如此反覆,丟棄TB
,Y
,TI
,TJ
和TK
:
trait TA{type X}
trait TC{self => type X <: TA{type X <: self.X}
class Z extends TC{type X = TA}
這編譯。而我們能做的
trait T1 extends TA{type X = T1}
trait T2 extends TA{type X = T1}
但是有一件事情我們不能做的:
trait TA {type X <: TA; def f(x: X)}
trait TC {self =>
type X <: TA{type X <: self.X}
def g(x: X) = x.f(x)
}
我們相處g
下面的錯誤,對於x
參數f
類型不匹配;實測值:x.type(與下面類型TC.this.X)所需 :x.x中
TC
是不完全原酮(如最初,g
被允許)。這是因爲TA
上有type X <: self.X
,而TC[X <: TA[X]]
是更強的type X = self.X
。如果我們寫出來,我們又回到原來的錯誤,Z
不編譯。所以這個TC
有點在原始的TC
(type X = self.X
)和TC2
(不知道TA的X)之間。再次,對原始代碼的限制,我們無法定義g
。
如果限制是可以接受的,你沒事。我不知道如何將它寫成通用的(也不知道如何用抽象類型成員編寫自我類型{self : X =>
)。邁爾斯絕對是專家,我敢肯定,他可以告訴他們做得如何,或者做不到這一點。
雖然我可以跟隨你的論點,但我認爲你已經通過改變Z的含義解決了問題.Z是一個傳統知識,因此在我的例子中是一個TC,但它不是,也不應該是TI。如果TC是一個「經理人」,那麼TA就是一個辦公室,而TB則是與經理人不在乎的辦公室相關的東西,TK是一個會計經理,TI是一個會計辦公室,那麼Z就是同時又是會計經理和會計部門。另外,我想指出,在我的真實代碼中,技術援助和結核病會有所不同,因爲他們會定義自己的行爲。 –
公平評論:我調整了上面Z的定義來解決它。請注意,您可以添加您想要的任何其他定義,TA,TB,TI,TJ ......您只需要重複類型成員即可。 –