パターンマッチングを使用できるケースクラスとしてRESTAPIからの応答をモデル化しようとしています。
継承を想定した場合に適していると思いましたが、これは非推奨であることがわかります。ケースクラスと継承に関連する質問がすでにあることは知っていますが、私の質問は、継承なしで次の「正しい方法」をどのようにモデル化するかについてです。
私は次の2つのケースクラスから始めました。これらは正常に機能します。
case class Body(contentType: String, content: String)
case class Response(statusCode: Int, body: Body)
つまり、REST呼び出しは次のようなもので返されます。
Response(200, Body("application/json", """{ "foo": "bar" }"""))
次のようにパターンマッチできます。
response match {
case Response(200, Body("application/json", json)) => println(json)
case Response(200, Body("text/xml", xml)) => println(xml)
case Response(_,_) => println("Something unexpected")
}
正常に動作するなど。
問題が発生したのは次のとおりです。次のような、これらのケースクラスのヘルパー拡張機能が必要です。
case class OK(body: Body) extends Response(200, body)
case class NotFound() extends Response(404, Body("text/plain", "Not Found"))
case class JSON(json: String) extends Body("application/json", json)
case class XML(xml: String) extends Body("text/xml", xml)
これにより、次のような単純化されたパターン一致を実行できます。
response match {
case OK(JSON(json)) => println(json)
case OK(XML(xml)) => println(xml)
case NotFound() => println("Something is not there")
// And still drop down to this if necessary:
case Response(302, _) => println("It moved")
}
また、RESTコードが直接使用して返すこともできます。
Response(code, Body(contentType, content))
これは、動的に応答を作成する方が簡単です。
それで...
私はそれを(非推奨の警告とともに)コンパイルすることができます:
case class OK(override val body: Body) extends Response(200, body)
ただし、これはパターンマッチングでは機能しないようです。
Response(200, Body("application/json", "")) match {
case OK(_) => ":-)"
case _ => ":-("
}
res0: java.lang.String = :-(
これがどのように機能するかについてのアイデアはありますか?私はさまざまなアプローチを受け入れていますが、これはケースクラスの実用的な使用法を見つけるための私の試みでした