acj*_*jay 7 json scala covariance spray-json
不确定这是一个错误,但以下演示在最终案例中失败:
import spray.json._
import DefaultJsonProtocol._
object SprayTest {
1.toJson
"".toJson
(Left(1): Either[Int, String]).toJson
(Right(""): Either[Int, String]).toJson
Seq(1).toJson
Seq("").toJson
Seq(Left(1), Right("")).toJson
Seq(Left(1), Right("")).toJson(seqFormat(eitherFormat(IntJsonFormat, StringJsonFormat)))
}
Run Code Online (Sandbox Code Playgroud)
所以所有的构建块似乎都有效,但是格式的组成Seq和Either失败,即使我尝试用勺子喂它.
我看到以下错误:
[error] SprayTest.scala:11: Cannot find JsonWriter or JsonFormat type class for Seq[Product with Serializable with scala.util.Either[Int,String]]
[error] Seq(Left(1), Right("")).toJson
[error] ^
[error] SprayTest.scala:12: type mismatch;
[error] found : spray.json.DefaultJsonProtocol.JF[Either[Int,String]]
[error] (which expands to) spray.json.JsonFormat[Either[Int,String]]
[error] required: spray.json.JsonFormat[Product with Serializable with scala.util.Either[Int,String]]
[error] Note: Either[Int,String] >: Product with Serializable with scala.util.Either[Int,String] (and spray.json.DefaultJsonProtocol.JF[Either[Int,String]] <: spray.json.JsonFormat[Either[Int,String]]), but trait JsonFormat is invariant in type T.
[error] You may wish to define T as -T instead. (SLS 4.5)
[error] Seq(Left(1), Right("")).toJson(seqFormat(eitherFormat(IntJsonFormat, StringJsonFormat)))
Run Code Online (Sandbox Code Playgroud)
知道是什么给出的吗?
Tra*_*own 14
这是关于最讨厌的事情之一Either-the Left和Right建设者都扩展Product和Serializable,但Either本身并没有,这会导致可怕的推断类型:
scala> Seq(Left(1), Right(""))
res0: Seq[Product with Serializable with scala.util.Either[Int,String]] = List(Left(1), Right())
Run Code Online (Sandbox Code Playgroud)
因为JsonFormat它的类型参数是不变的,所以你有一个实例的A事实并不意味着你有一个实例Product with Serializable with A.在具体情况下,实际上有一个实例Either[Int, String],但推断类型中的额外垃圾意味着编译器无法找到它.
如果Right顺序中没有a ,会发生类似的事情:
scala> Seq(Left(1), Left(2)).toJson
<console>:18: error: Cannot find JsonWriter or JsonFormat type class for Seq[scala.util.Left[Int,Nothing]]
Seq(Left(1), Left(2)).toJson
^
Run Code Online (Sandbox Code Playgroud)
您可以通过提供类型而不是使用推断的类型来解决这两个问题:
scala> val xs: Seq[Either[Int, String]] = Seq(Left(1), Right(""))
xs: Seq[Either[Int,String]] = List(Left(1), Right())
scala> xs.toJson
res1: spray.json.JsValue = [1,""]
Run Code Online (Sandbox Code Playgroud)
在许多情况下,这不是问题,因为您经常Either从显式返回Either而不是使用的方法中获取值,Left并Right直接以导致此问题的方式获取.
作为脚注:这就是为什么Product with Serializable在定义自己的ADT 时应始终保持根密封特性(或密封类)的原因.如果标准图书馆设计师遵循这一建议,我们会好得多.
| 归档时间: |
|
| 查看次数: |
843 次 |
| 最近记录: |