我有一个通用特征MappingPath,关于它的类型参数是不变的:
trait MappingPath[X<:AnyMapping, Y<:AnyMapping]
以及它的工厂界面:
trait Pathfinder[X, Y] {
def apply(fun :X=>Y) :MappingPath[_<:AnyMapping,_<:AnyMapping]
def get(fun :X=>Y) :Option[MappingPath[_<:AnyMapping, _<:AnyMapping]]
}
我启动了一个适用于单个映射的框架实现:
class MappingPathfinder[M<:AnyMapping, X, Y] extends Pathfinder[X, Y] {
override def apply(fun :X=>Y) :MappingPath[M, _<:AnyMapping] = ???
override def get(fun :X=>Y) :Option[MappingPath[M, _<:AnyMapping]] = ???
}
产生编译错误,抱怨MappingPathfinder.apply
无法覆盖任何内容并且未实现Pathfinder.apply
。有趣的是,在M
的返回类型中用_<:AnyMapping
替换apply
会使其编译,并且不会对类似get
方法提出任何投诉。
发生了什么事?我使用scala 2.11.5。
编辑: 我能够通过添加明确的存在性注释来解决我的问题:
//Pathfinder
def apply(fun :X=>Y) :MappingPath[A, B] forSome { type A<:AnyMapping; type B<:AnyMapping }
//MappingPathfinder
def apply(fun :X=>Y) :MappingPath[A, B] forSome { type A>:M<:M; type B<:AnyMapping }
似乎有用,即 我能做到:
(p :MappingPath[_<:AnyMapping, M]) ++ mappingPathfinder(f),
其中++
要求路径以与this
完全相同的类型开头。它看起来有点傻,但肯定令人困惑。
答案 0 :(得分:2)
不是答案,但您的用例可以简化为:
trait Higher[U]
trait Super {
def foo: Higher[_]
}
trait Sub[M] {
override def foo: Higher[M] // error: method foo overrides nothing
}
我会使用类型成员而不是存在类型:
trait Super {
type U
def foo: Higher[U]
}
trait Sub[M] {
type U = M
}
我认为不同之处在于,在存在类型的情况下,您只指定返回的类型参数具有某个上限,但不一定是它始终相同的类型;而在我的第二个示例中,type U
表示最终将一个特定类型,并且您只能优化特定类型。您可以使上限更精确:
trait Upper
trait A {
type U <: Upper
}
trait Specific extends Upper
trait B extends A {
type U <: Specific // type is "overridden"
}
如果有可能,我会避免存在类型,你的情况似乎非常适合这种避免。大多数情况下,只有Java互操作才需要存在类型。