Моделирование с помощью класса case Scala

Я пытаюсь смоделировать ответы от REST API как кейс-классы, для которых я могу использовать сопоставление с образцом.

Я думал, что было бы неплохо принять наследование, но я вижу, что это устарело. Я знаю, что уже есть вопросы, связанные с case-классами и наследованием, но мой вопрос больше о том, как вы могли бы смоделировать следующий «правильный путь» здесь без наследования.

Я начал со следующих двух case-классов, которые отлично работают:

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, такие как:

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 = :-(

Есть идеи, как это могло бы работать? Я открыт для разных подходов, но это была моя попытка найти практическое применение кейс-классам

6
задан 0__ 25 June 2012 в 02:10
поделиться