将 Json4S 迁移到 Circe
Migrating for Json4S to Circe
我有以下用 json4s 编写的代码,可以编译并正常工作
import org.json4s._
def jsonRead[T <: AnyRef](input: String)(implicit m: Manifest[T]): T = {
Try(read[T](input)).get
}
def jsonWrite[T <: AnyRef](input: T)(implicit m: Manifest[T]): String = {
write[T](input).toString
}
我写了下面的Circe代码
import io.circe._
import io.circe.syntax._
import io.circe.generic.auto._
import io.circe.parser.decode
def unmarshall[T <: AnyRef](input: String)(implicit m: Manifest[T]) : T ={
decode[T](input).right.get
}
def marshall[T <: AnyRef](input: T)(implicit m: Manifest[T]) : String = {
input.asJson.toString
}
但是我得到了错误
Error:(27, 16) could not find implicit value for parameter decoder: io.circe.Decoder[T] decode[T](json).right.get
Error:(27, 16) not enough arguments for method decode: (implicit decoder: io.circe.Decoder[T])Either[io.circe.Error,T]. Unspecified value parameter decoder. decode[T](json).right.get
Error:(30, 11) could not find implicit value for parameter encoder: io.circe.Encoder[T] obj.asJson.toString
Error:(30, 11) not enough arguments for method asJson: (implicit encoder: io.circe.Encoder[T])io.circe.Json. Unspecified value parameter encoder. obj.asJson.toString
json4s
和 circe
是不同的库,它们以不同的方式工作,这就是为什么你不能使用相同的技术。虽然 json4s
read
需要一个清单来从 Json 中提取一个值,但 circe
需要一个类型类 Decoder
的实例。如果你想在你的例子中使用 circe
你应该写类似
def unmarshall[T <: AnyRef](input: String)(implicit d: Decoder[T]) : T = {
decode[T](input).right.get
}
def marshall[T <: AnyRef](input: T)(implicit e: Encoder[T]) : String = {
input.asJson.toString
}
要了解我建议阅读这两个实现的差异,它们对于理解这两个库如何做它们的工作非常有用。您可以在 json4s native read
and circe decode
. I will copy here the important bits of the signatures to explain the fundamental difference between the two libraries. The signature of json4s native read
is
的签名中看到差异
def read[A](input: String)(implicit mf: Manifest[A]): A
可以解释为"I can convert a String into any type A if you provide a Scala Manifest for it"。因为 Manifest
是用于反射的 Scala 特性,所以可以推断 read
将使用反射。
circedecode
的签名不同:
def decode[A](input: String)(implicit d: Decoder[A]): Either[Error, A]
可以读作"I can try to convert a String into a type A if you provide a circe Decode instance for it"。 Decoder
类型类只是告诉系统如何从 json.
解码 A
类型的值
我有以下用 json4s 编写的代码,可以编译并正常工作
import org.json4s._
def jsonRead[T <: AnyRef](input: String)(implicit m: Manifest[T]): T = {
Try(read[T](input)).get
}
def jsonWrite[T <: AnyRef](input: T)(implicit m: Manifest[T]): String = {
write[T](input).toString
}
我写了下面的Circe代码
import io.circe._
import io.circe.syntax._
import io.circe.generic.auto._
import io.circe.parser.decode
def unmarshall[T <: AnyRef](input: String)(implicit m: Manifest[T]) : T ={
decode[T](input).right.get
}
def marshall[T <: AnyRef](input: T)(implicit m: Manifest[T]) : String = {
input.asJson.toString
}
但是我得到了错误
Error:(27, 16) could not find implicit value for parameter decoder: io.circe.Decoder[T] decode[T](json).right.get
Error:(27, 16) not enough arguments for method decode: (implicit decoder: io.circe.Decoder[T])Either[io.circe.Error,T]. Unspecified value parameter decoder. decode[T](json).right.get
Error:(30, 11) could not find implicit value for parameter encoder: io.circe.Encoder[T] obj.asJson.toString
Error:(30, 11) not enough arguments for method asJson: (implicit encoder: io.circe.Encoder[T])io.circe.Json. Unspecified value parameter encoder. obj.asJson.toString
json4s
和 circe
是不同的库,它们以不同的方式工作,这就是为什么你不能使用相同的技术。虽然 json4s
read
需要一个清单来从 Json 中提取一个值,但 circe
需要一个类型类 Decoder
的实例。如果你想在你的例子中使用 circe
你应该写类似
def unmarshall[T <: AnyRef](input: String)(implicit d: Decoder[T]) : T = {
decode[T](input).right.get
}
def marshall[T <: AnyRef](input: T)(implicit e: Encoder[T]) : String = {
input.asJson.toString
}
要了解我建议阅读这两个实现的差异,它们对于理解这两个库如何做它们的工作非常有用。您可以在 json4s native read
and circe decode
. I will copy here the important bits of the signatures to explain the fundamental difference between the two libraries. The signature of json4s native read
is
def read[A](input: String)(implicit mf: Manifest[A]): A
可以解释为"I can convert a String into any type A if you provide a Scala Manifest for it"。因为 Manifest
是用于反射的 Scala 特性,所以可以推断 read
将使用反射。
circedecode
的签名不同:
def decode[A](input: String)(implicit d: Decoder[A]): Either[Error, A]
可以读作"I can try to convert a String into a type A if you provide a circe Decode instance for it"。 Decoder
类型类只是告诉系统如何从 json.
A
类型的值