【发布时间】:2017-04-21 01:55:33
【问题描述】:
以下是我原始代码的简化版本,让事情变得更简单(抱歉还是有点复杂):
trait BuilderBase
trait MessageBase {
type Builder <: BuilderBase
}
class SomeMessage extends MessageBase {
type Builder = SomeMessage.Builder
}
object SomeMessage {
class Builder extends BuilderBase
}
class Covariant[+T]
class NonCovariant[T]
def func[T <: MessageBase](value: Covariant[T]): Covariant[T#Builder] = null
val message: Covariant[SomeMessage] = null
val result: Covariant[SomeMessage.Builder] = func(message)
最后一行编译失败,在func(→ message ← here)报错:
类型不匹配;发现:需要协变[SomeMessage]:协变[SomeMessage.type]
func 肯定接受 T 的 Covariant 参数,它是 MessageBase 的子类,这里需要的是 Covariant[SomeMessage] 而不是 Covariant[SomeMessage.type],因为 SomeMessage.type(伴生对象 SomeMessage 的类型)不符合 MessageBase .
奇怪的是,没有类型注释,错误就消失了,比如val result = func(message),结果的类型与它的含义完全相同:协变[SomeMessage.Builder]。所以它只是失败了正确的类型注释。这是一个错误吗?
另一个线索是,所有 Covariant 都替换为 NonConvariant 时不会发生这种情况。所以它可能与协方差有关。任何建议或帮助将不胜感激。
我知道一些小调整可以解决这个特定问题,例如简单地省略类型注释可能就是其中之一。但是,如果我能获得更多关于编译器实际情况的线索,例如通过提供一些命令行选项,那将非常有帮助。
【问题讨论】:
标签: scala type-inference