Ich möchte eine Art Sicherheit in der folgenden Situation erreichen.Scala: Typ Inferenz fehlt etwas
Grundsätzlich habe ich verschiedene Arten von Anfragen, die in einer Datenbank gespeichert sind, deren Typ mit einem String-Code identifiziert wird. Aus geschäftlichen Gründen entspricht dieser Code nicht den Klassennamen.
Jeder Anfragetyp enthält eine Art Nutzlast, der Typ der Nutzlast hängt direkt von der Art der Anfrage ab. Hier
ist eine vereinfachte Version von dem, was ich erreicht habe, so weit:
trait Request[Payload] {
def metadata: String // Not relevant
def payload: Payload
}
case class RequestWithString(override val metadata: String, override val payload: String) extends Request[String]
case class AnotherTypeOfRequestWithString(override val metadata: String, override val payload: String) extends Request[String]
case class RequestWithInt(override val metadata: String, override val payload: Int) extends Request[Int]
object Request {
def apply(code: String)(metadata: String, payload: Any): Request[_] = code match {
case "S" => RequestWithString(metadata, payload.asInstanceOf[String])
case "S2" => AnotherTypeOfRequestWithString(metadata, payload.asInstanceOf[String])
case "I" => RequestWithInt(metadata, payload.asInstanceOf[Int])
}
}
Dies ist nicht befriedigend, wie ich Scala möchte die Art der Nutzlast schließen Gießen zu vermeiden, und die (parametrisierte) Typ des zurückgegebenen Werts.
Was ich suche ist so etwas wie das:
object Request {
def apply[P, R <: Request[P]](code: String)(metadata: String, payload: P): R = code match {
case "S" => RequestWithString(metadata, payload)
case "S2" => AnotherTypeOfRequestWithString(metadata, payload)
case "I" => RequestWithInt(metadata, payload)
}
}
Aber dies scheint nicht zu arbeiten, kann ich nicht von einigen Typdiskrepanzen loszuwerden:
found : P
required: String
case "S" => RequestWithString(metadata, payload)
^
shouldn‘ Scala folgert, dass P in diesem Fall String ist? Was vermisse ich?
Welche weiteren Verarbeitung sind Sie auf jede Art von Anfrage zu tun? –
@YuvalItzchakov: MongoDB-Speicher mit ReactiveMongo, der dann einen lesbaren Text aus den Payload- und Remote-Daten erstellt, um den Text an ein entferntes System zu senden. Ich muss zu MongoDB lesen/schreiben, der Hauptzweck der Request.apply Funktion soll in einem BSONReader [Request] aufgerufen werden. –
Aktuelle Antworten helfen sehr. Allerdings habe ich bearbeitet, um klarer zu machen, dass die Art der Anfrage nicht nur vom Typ der Nutzlast abhängt. Möglicherweise gibt es mehrere Unterklassen mit der gleichen Art von Payload. –