迁移Json4S到Circe

Kno*_*uch 3 scala 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
}
Run Code Online (Sandbox Code Playgroud)

我写了以下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
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了错误

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
Run Code Online (Sandbox Code Playgroud)

mar*_*iop 7

json4s并且circe是不同的库以不同的方式工作,这就是为什么你不能使用相同的技术.虽然json4s read需要Manifest从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
}
Run Code Online (Sandbox Code Playgroud)

为了理解我建议阅读这两个实现的差异,它们对于理解两个库如何完成它们的工作非常有用.您可以在json4s native read和circe 的签名中看到差异decode.我将在这里复制签名的重要部分,以解释两个库之间的根本区别.json4s原生的签名read

def read[A](input: String)(implicit mf: Manifest[A]): A
Run Code Online (Sandbox Code Playgroud)

这可以解释为"如果你为它提供Scala Manifest,我可以将一个字符串转换为任何类型的A".因为Manifest是用于反射的Scala特征,所以可以推断出read将使用反射.

circe的签名decode是不同的:

def decode[A](input: String)(implicit d: Decoder[A]): Either[Error, A]
Run Code Online (Sandbox Code Playgroud)

可以读作"如果你为它提供一个Circe Decode实例,我可以尝试将一个String转换为一个类型A".该Decoder类型类只是告诉系统如何解码类型的值A从JSON.