2015-06-26 94 views
10

這將編譯:爲什麼在這個Scala代碼中需要向上轉換?

import scala.collection._ 

trait Foo[A, +This <: SortedSet[A] with SortedSetLike[A,This]] 
extends SortedSetLike[A, This] { this: This => 

    def bar: This = (this: SortedSetLike[A,This]).empty 

} 

但如果上溯造型被刪除它未能編譯:

import scala.collection._ 

trait Foo[A, +This <: SortedSet[A] with SortedSetLike[A,This]] 
extends SortedSetLike[A, This] { this: This => 

    def bar: This = this.empty 

} 

爲什麼?從extends子句我們知道FooSortedSetLike[A, This],所以upcast當然是有效的 - 但是這不表明編譯器允許發生衝突繼承嗎?

+2

我不知道這種情況的具體細節,但它是可能發生的可怕事情的另一個例子,因爲子類中的方法可能比它們實現的方法簽名具有更多特定的返回類型。 –

回答

3

SortedSetLike性狀繼承SetLike方法。

/** The empty set of the same type as this set 
* @return an empty set of type `This`. 
*/ 
def empty: This 

的SortedSet覆蓋方法,並有明確的返回類型:

/** Needs to be overridden in subclasses. */ 
override def empty: SortedSet[A] = SortedSet.empty[A] 

既然你指定SortedSet的一個子類,編譯器會發現SortedSet的執行首先,它返回一個SortedSet。編譯器不知道如何將生成的SortedSet轉換爲您的這個子類。

但如果上溯造型到SortedSetLike特質,編譯器會發現它方法,它返回一個

相關問題