Ich versuche, Antworten von REST-APIs als Fallklassen zu modellieren, für die ich die Mustererkennung verwenden kann.Modellierung mit Scala-Fallklasse
Ich dachte, es wäre eine gute Passform unter Annahme der Vererbung, aber ich sehe, dass dies veraltet ist. Ich weiß, es gibt bereits Fragen im Zusammenhang mit Fallklassen und Vererbung, aber meine Frage ist mehr darüber, wie Sie das folgende "den richtigen Weg" hier ohne Vererbung modellieren würden.
ich mit den folgenden zwei Fallklassen gestartet, die gut funktionieren:
case class Body(contentType: String, content: String)
case class Response(statusCode: Int, body: Body)
dh ein REST Anruf zurückkehren würde mit so etwas wie:
Response(200, Body("application/json", """{ "foo": "bar" }"""))
welche ich konnte Mustererkennung wie:
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")
}
usw. das funktioniert gut.
Wo ich in Schwierigkeiten lief ist: Ich Helfer Erweiterungen für diesen Fall Klassen möchten, wie zum Beispiel:
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)
so dass ich Muster wie diese Spiele vereinfacht tun können:
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")
}
und die auch erlauben würde, dass mein REST-Code direkt verwendet und zurückgegeben wird:
Response(code, Body(contentType, content))
was ist e asier, dynamisch eine Antwort zu erstellen.
so ...
Ich kann es (mit deprecation Warnungen) zu kompilieren über:
case class OK(override val body: Body) extends Response(200, body)
Allerdings scheint dies nicht mit Mustervergleich zu arbeiten.
Response(200, Body("application/json", "")) match {
case OK(_) => ":-)"
case _ => ":-("
}
res0: java.lang.String = :-(
Irgendwelche Ideen, wie dies funktionieren könnte? Ich bin offen für verschiedene Ansätze, aber das war mein Versuch, eine praktische Verwendung für Fallklassen zu finden
Ah, danke - ich sehe, ich habe den Zweck der unapply bis zu diesem völlig verpasst; das ist sehr hilfreich. Ich werde das mit meinem Code austesten, um sicherzugehen, dass ich mich bedeckt habe und später Abend annehmen werde. – 7zark7
Gute Antwort @Sciss. Benutzerdefinierte Extraktoren sind eine der Sachen, die ich sehr an Scala mag. – mergeconflict
@ 7zark7 Beachten Sie, dass Sie bei Verwendung von benutzerdefinierten Extraktoren die Vollständigkeit der garantierten Klassen verlieren. –