2015-06-26 49 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特质,编译器会发现它方法,它返回一个

相关问题