2

私は Scala を初めて使用し、特に Unfiltered ( http://unfiltered.databinder.net/Try+Unfiltered.html ) の例から、パターン マッチング構造の構文を理解しようとしています。

Hello World! をエコー バックする単純な HTTP サーバーを次に示します。パスが 2 つの部分からなる場合は、パスの 2 つの部分:

package com.hello

import unfiltered.request.GET
import unfiltered.request.Path
import unfiltered.request.Seg
import unfiltered.response.ResponseString

object HelloWorld {
  val sayhello = unfiltered.netty.cycle.Planify {
    case GET(Path(Seg(p :: q :: Nil))) => {
      ResponseString("Hello World! " + p + " " + q);
    }
  };

  def main(args: Array[String]) {
    unfiltered.netty.Http(10000).plan(sayhello).run();
  }
}

Path、Seg、および GET/Method オブジェクトのソース コードも参照してください。

package unfiltered.request

object Path {
  def unapply[T](req: HttpRequest[T]) = Some(req.uri.split('?')(0))
  def apply[T](req: HttpRequest[T]) = req.uri.split('?')(0)
}

object Seg {
  def unapply(path: String): Option[List[String]] = path.split("/").toList match {
    case "" :: rest => Some(rest) // skip a leading slash
    case all => Some(all)
  }
}

class Method(method: String) {
  def unapply[T](req: HttpRequest[T]) = 
    if (req.method.equalsIgnoreCase(method)) Some(req)
    else None
}

object GET extends Method("GET")

私はそれがどのように機能するかを分解することができましたが、この行は私を困惑させます:

case GET(Path(Seg(p :: q :: Nil))) => {

コードの目的は理解できますが、それがどのように適用されるかはわかりません。私は単に HTTP サーバーを実装するのではなく、Scala の詳細を学ぶことに非常に興味があるので、これについて数時間掘り下げてきました。、、およびオブジェクトのエクストラクタとunapplyメソッドに関係があることを理解しています。また、デバッグするとbeforeとbeforeにヒットすることも知っています。GETPathSegunapplyGETPathPathSeg

次のことがわかりません。

  1. なぜ私は書くことができないのに、 orGET.unapply(req)を書くことができ、どの HTTP GET とも一致するのでしょうか?GET(req)GET()

  2. unapplyコンパイラは、各エクストラクタのメソッドに渡される値をなぜ、またはどのように知るのでしょうか? どちらかが?のNone代わりにa を返さない限り、それらを連鎖させるだけのようです。Some

  3. 変数 p と q をどのようにバインドしますか? それらが文字列であることはわかっています。戻り値の型からそれを推測する必要がありSeg.unapplyますが、リストの最初の部分の値を p に、リストの 2 番目の部分の値を q に割り当てるメカニズムがわかりません。

  4. 何が起こっているのかをより明確にするために書き直す方法はありますか?この例を最初に見たとき、行に戸惑いました val sayhello = unfiltered.netty.cycle.Planify {。掘り下げて書き直したところ、暗黙的に PartialFunction を作成して Planify.apply に渡していることがわかりました。

4

1 に答える 1