为啥在这个 Scala 代码中需要向上转换?
Posted
技术标签:
【中文标题】为啥在这个 Scala 代码中需要向上转换?【英文标题】:Why is upcasting necessary in this Scala code?为什么在这个 Scala 代码中需要向上转换? 【发布时间】:2015-06-26 18:58:50 【问题描述】:这样编译:
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
但是如果删除了upcast,它就无法编译:
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
子句中,我们知道Foo
是SortedSetLike[A, This]
,所以向上转换当然是有效的——但这是否表明编译器允许发生冲突继承?
【问题讨论】:
我不知道这个案例的确切细节,但这是另一个可能发生的可怕事情的例子,因为子类中的方法可以具有比它们实现的方法签名更具体的返回类型。跨度> 【参考方案1】:SortedSetLike trait 继承了 SetLike 的 empty 方法。
/** The empty set of the same type as this set
* @return an empty set of type `This`.
*/
def empty: This
但是 SortedSet 覆盖了 empty 方法并且有一个明确的返回类型:
/** Needs to be overridden in subclasses. */
override def empty: SortedSet[A] = SortedSet.empty[A]
由于您指定 This 是 SortedSet 的子类,编译器将找到 SortedSet 的 empty实现> 首先,它返回一个 SortedSet。编译器不知道如何将生成的 SortedSet 转换为您的 This 子类。
但是如果你向上转换到 SortedSetLike 特征,编译器会发现它的 empty 方法返回一个 This。
【讨论】:
以上是关于为啥在这个 Scala 代码中需要向上转换?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我们需要 dequeueReusableCell func 获得的向上转换单元格?
Scala 性能:为啥这个 Scala 应用程序比同等的 Java 应用程序慢 30 倍?