Jea*_*let 14 scala lift partialfunction
PartialFunction简而言之,在Scala中,a 是另外定义isDefinedAt方法的函数.
使用一系列case语句很容易定义部分函数.一个简单的例子是,例如:
scala> val pf: PartialFunction[Int, Unit] = {
| case 42 => ()
| }
pf: PartialFunction[Int,Unit] = <function1>
scala> pf.isDefinedAt(42)
res0: Boolean = true
scala> pf.isDefinedAt(0)
res1: Boolean = false
Run Code Online (Sandbox Code Playgroud)
isDefinedAt从case定义部分函数的s 列表中自动生成.
Lift框架在许多地方使用部分功能,例如定义一个请求是应该由Lift的引擎处理还是直接从磁盘上的文件提供服务.有时候,我发现自己想要编写一个case匹配所有输入参数的语句,然后才决定是否要返回一个值.这意味着cases 的初始序列不再足以确定我的函数是否定义在给定值
例如,在Lift中,我想添加一个规则,直接提供所有html和htm文件,并且应该处理带有"lift"扩展名的文件.做这样的事情会很容易:
LiftRules.liftRequest.prepend {
case Req(path, extension, tpe) => extension match {
case "html" | "htm" => false
case "lift" => true
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,在这种情况下,编译器认为我的部分函数是在任何地方定义的,因为第一个case总是匹配.嵌套match可能与所有传入请求不匹配.而且,请求是不匹配的,MatchError是抛出的.
有没有一种简单的方法可以让编译器match在定义部分函数时考虑嵌套语句,或者是唯一的方法来内联所有这样的嵌套条件?
LiftRules.liftRequest.prepend {
case Req(path, extension, tpe) if extension == "html" || extension == "htm" => false
case Req(path, extension, tpe) if extension == "lift" => true
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,它在很大程度上是可行的,但是可读性降低了,而且我遇到了内联所有检查看起来非常难看的情况.
Deb*_*ski 23
在这种情况下,您可能想要写
LiftRules.liftRequest.prepend {
case Req(path, "html" | "htm", tpe) => false
case Req(path, "lift", tpe) => true
}
Run Code Online (Sandbox Code Playgroud)
对于更复杂的情况,您需要定义自己的提取器,而不是嵌套case语句.
object CheckExtension {
def unapply(ext: String) = ext match {
case "lift" => Some(true)
case "html" | "htm" => Some(false)
case _ => None
}
}
LiftRules.liftRequest.prepend {
case Req(path, CheckExtension(valid), tpe) => valid
}
Run Code Online (Sandbox Code Playgroud)
只有在预定义unapply函数返回Some并将值赋给Some自由变量时,才会匹配valid.如果unapply返回None,则不生成匹配项.
| 归档时间: |
|
| 查看次数: |
802 次 |
| 最近记录: |