我的场景是这样的:
trait A {
type B
def foo(b: B)
}
trait C[D <: A] {
val d: D
def createB(): D#B
def bar() {
d.foo(createB)
}
}
在 REPL 中,它会提示
<console>:24: error: type mismatch;
found : D#B
required: C.this.d.B
a.bar(createB())
这有什么问题?以及(如果可能的话)如何更正此代码?
最佳答案
D#B
是类型投影,与d.B
不同。您的类型不匹配,因为在 foo
中,B
实际上意味着 this.B
,这与 D# 不同B
(后者更通用)。
非正式地,您可以将 D#B
视为表示抽象类型 B
可以为 D
的任何实例采用的任何可能类型,而 d.B
是特定实例 d
的 B
的类型。
参见 What does the `#` operator mean in Scala?和 What is meant by Scala's path-dependent types?对于某些上下文。
使其编译的一种方法是将 createB
的返回类型更改为 d.B
:
def createB(): d.B
但是在很多情况下,这样的解决方案限制太多,因为您被绑定(bind)到特定实例 d
,这可能不是您想要的。
另一种解决方案是用类型参数替换抽象类型(尽管它更冗长):
trait A[B] {
def foo(b: B)
}
trait C[B, D <: A[B]] {
val d: D
def createB(): B
def bar() {
d.foo(createB)
}
}
关于scala - 引用类型参数的抽象类型成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29388642/