【发布时间】:2015-05-17 14:57:51
【问题描述】:
我有一个通用特征 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。有趣的是,在apply 的返回类型中将M 替换为_<:AnyMapping 使其可以编译,并且没有对类似的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 结尾完全相同的类型开头的路径。它看起来有点傻,但肯定令人困惑。
【问题讨论】:
-
Afaik,
def apply(): MappingPath[_<: AnyMapping, _ <: AnyMapping]与def apply[A <: AnyMapping, B <: AnyMapping](): MappingPath[A, B]相同。这样看,我们可以看到签名def apply[B <: AnyMapping](): MappingPath[M, B]不匹配。但是,那些存在类型真的让我很困惑,我无法弄清楚为什么get会编译。如果您只是在寻找解决方案,我会说不要使用存在类型,而是使用M <: AnyMapping参数化PathFinder。 -
真的等价吗?在扩展形式中,调用者可以指定结果特化,而我期望(或至少想要)返回一个真正的 ..[T] forSome { type T}。当然可以在父类型中有一个 Seq[_] 的成员声明并将其覆盖为 Seq[T],其中 T 是覆盖类类型参数,这就是我想要的。
标签: scala generics existential-type