【发布时间】:2013-09-14 04:25:26
【问题描述】:
下面是我有时会遇到参数化类型的一种情况的具体实例。基本上,我知道有些类型参数是兼容的,但我不知道如何向代码的某些部分证明这一点。
我正在编写一个将 url 映射到处理函数的请求路由器。下面是一些简化的代码。我创建了一个List[Route],其中Route 基本上是一对UrlMatcher, Function。
class Route[A](matcher: UrlMatcher[A], handler: HandlerFunction[A])
abstract class UrlMatcher[A] {
def match(url: String): Option[A] // None if no match
类型参数A 用于匹配器可能从 URL 中提取的“参数”。它们将被传递给处理函数。例如,看到类似“/users/123”的 URL 路径的 UrlMatcher[Int] 可以将 123 传递给 getUser(id: Int) 函数。路由器可能如下所示:
val routes = ArrayBuffer[Route[_]]
def callHandler(url: String) {
for (r <- routes) {
val args = r.matcher.matchUrl(url)
if (args.isDefined)
r.handler(args.get) // <--- error here
}
问题是我得到类型不匹配错误,因为我不知道如何告诉它这两种类型是相同的。
type mismatch; found: args.type (with underlying type Option[Any])
required: _$1
我知道我可以重新设计它,以便 Route 具有类似 matchAndCall 的方法,但如果可能的话,我想保持这种逻辑流程。
更新/编辑
我不完全理解存在类型,但我试过这个......
val routes = ArrayBuffer[T forSome { type T }]()
并且它消除了上面的不匹配错误。但是,我还有一个插入到ArrayBuffer 的位置。
def route[P](matcher: UrlMatcher[P], handler: Handler[P]): AbstractRoute = {
val route = new Route(matcher, handler)
otherRoutes.append(route) // error here
route
}
现在错误是...
type mismatch; found : Route[P] required: Route[T forSome { type T }] Note: P <: T
forSome { type T }, but class Route is invariant in type P. You may wish to define
P as +P instead. (SLS 4.5)
为什么P 与T 不兼容,因为它们对T 没有约束?
【问题讨论】:
标签: scala type-systems type-mismatch existential-type parameterized-types