3

我有以下用 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
4

1 回答 1

7

json4s并且circe是不同的库以不同的方式工作,这就是为什么你不能使用相同的技术。虽然json4s read需要 Manifest 从 Json 中提取值,但circe需要 typeclass 的实例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 nativeread和 circe的签名中看到差异decode。我将在这里复制签名的重要部分,以解释两个库之间的根本区别。json4s native的签名read

def read[A](input: String)(implicit mf: Manifest[A]): A

这可以解释为“如果您为其提供 Scala Manifest,我可以将 String 转换为任何类型 A”。因为Manifest是用于反射的 Scala 特征,所以您可以推断出read将使用反射。

circe 的签名decode不同:

def decode[A](input: String)(implicit d: Decoder[A]): Either[Error, A]

可以理解为“如果您为其提供 circe Decode 实例,我可以尝试将 String 转换为 A 类型”。typeclassDecoder只是告诉系统如何A从 json 解码类型的值。

于 2016-12-26T16:10:57.117 回答