1

我需要定义一些部分函数来处理具有不同模式的不同 url(使用 unfinagled):

def indexRoute:PartialFunction[Request, Response] = { 
   case Path("index") => Ok ~> ResponseString("hello")
}

def notFound:PartialFunction[Request, Response] = { 
    case Path(_) => NotFound
}

def assetsRoutes:PartialFunction[Request, Response] = { 
    case Path("assets" :: tail) =>
      loadResourceContent(tail) match {
          case Some(content) => Ok ~> ResponseString(content)
          case _ => NotFound // !!! I don't want to handle it here
      }
}

val allRoutes = indexRoute orElse assetsRoutes orElse notFound

你可以看到我最终将一些部分功能组合成一个完整的路线。最后一个是NotFound处理不匹配的url,所以我不想关心早期路由中的不匹配情况(比如,assertRoutes)。

但是在该assetsRoutes方法中,我无法轻松检查资产是否存在于case零件中,因为我只想为资产触摸一次文件系统。所以我不想写:

def assetsRoutes:PartialFunction[Request, Response] = { 
    case Path("assets" :: tail) if resoueceExist(tail)=>
      val content = loadResourceContent(tail).get 
      Ok ~> ResponseString(content)
}

虽然我可以编写unapply如下自定义:

object AssetExistWithContent {

  def unapply(req:Request): Option[String] =  {
    req match {
      case Path("assets" :: tail) => loadResourceContent(tail)
      case _ => None
    }
  }
}

def assetsRoutes:PartialFunction[Request, Response] = { 
    case AssetExistWithContent(content) => Ok ~> ResponseString(content)
}

case AssetExistWithContent(content)但我认为在匹配 url 或请求时看不到部分。

所以我想知道是否可以取消函数体中的当前部分函数?所以我可以写:

def assetsRoutes:PartialFunction[Request, Response] = { 
    case Path("assets" :: tail) =>
      loadResourceContent(tail) match {
          case Some(content) => Ok ~> ResponseString(content)
          case _ => cancelThisPartialFunction // !!!
      }
}

在这个方法中我不需要关心什么时候做(NotFound 或其他事情),只要告诉调用者我无法处理它,请尝试下一个。

4

1 回答 1

3

PartialFunction如您所描述的,无法取消 a 。但是,您可以定义一个更简单的提取器:

object LoadableContent {
  def unapply(req: List[String]): Option[String] = loadResourceContent(req)
}

并像这样使用它:

def assetsRoutes: PartialFunction[Request, Response] = { 
    case Path("assets" :: LoadableContent(content)) =>
      Ok ~> ResponseString(content)
}
于 2014-07-08T14:09:18.290 回答