我想在以下情况下实现某种类型的安全。Scala:类型推断丢失了一些东西
基本上,我有不同类型的请求存储在数据库中,它们的类型用一些字符串代码标识。出于商业原因,此代码不会与匹配的类名称。
每种类型的请求都包含某种有效负载,有效负载的类型直接取决于请求的类型。
下面是我迄今取得的简化版本:
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])
}
}
这不是令人满意的,因为我想斯卡拉推断有效负载的类型,以避免铸造,以及(参数化)类型的返回值。
我所寻找的是类似的东西:
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)
}
}
但是这似乎并没有工作,我无法摆脱某种类型不匹配的错误:
found : P
required: String
case "S" => RequestWithString(metadata, payload)
^
不该”在这种情况下,Scala推断P是String吗?我错过了什么?
你在每个类型的请求做什么进一步的处理? –
@YuvalItzchakov:带有ReactiveMongo的MongoDB存储,然后从有效负载和远程数据中编写人类可读的文本,以便将文本发送到远程系统。 我需要读取/写入MongoDB,Request.apply函数的主要目的是在BSONReader [Request]中调用。 –
现在的答案帮了很大忙。但是,我编辑了一下,使其更清楚,请求的类型不仅取决于有效负载的类型。可能有几个具有相同类型Payload的Request子类。 –