1

さまざまなパターン (unfinagled) を持つさまざまな URL を処理するために、いくつかの部分関数を定義する必要があります。

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

最後に、いくつかの部分的な関数を組み合わせて完全なルートにしたことがわかります。最後の 1 つは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あなたが説明しているようにキャンセルする方法はありません。ただし、より単純なエクストラクタを定義できます。

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 に答える