circe 如何将泛型类型对象解析为 Json? [英] How does circe parse a generic type object to Json?
问题描述
这是我想要做的
case class MessageModel (time: Long, content: String) {}
val message = MessageModel(123, "Hello World")
def jsonParser[A] (obj: A) : String = obj.asJson.noSpaces
println jsonParser[MessageModel](message)
这不起作用,因为它会抱怨错误:(13, 8) 找不到参数编码器的隐式值:io.circe.Encoder[A] obj.asJson.noSpaces^
this doesn't work, because it will complain Error:(13, 8) could not find implicit value for parameter encoder: io.circe.Encoder[A] obj.asJson.noSpaces ^
我有点理解为什么会这样,但是有没有办法解决它?
I kind of understand why it is happening, but is there a way to work around it?
谢谢
推荐答案
circe 中的编码和解码是由类型类提供的,这意味着你必须能够在编译时证明你有一个类型类实例 A
如果要编码(或解码)A
类型的值.
Encoding and decoding in circe are provided by type classes, which means that you have to be able to prove at compile time that you have a type class instance for A
if you want to encode (or decode) a value of type A
.
这意味着当你写这样的东西时:
This means that when you write something like this:
import io.circe.syntax._
def jsonPrinter[A](obj: A): String = obj.asJson.noSpaces
您没有为 circe 提供关于 A
的足够信息,无法打印该类型的值.您可以使用上下文绑定来解决此问题:
You're not providing enough information about A
for circe to be able to print values of that type. You can fix this with a context bound:
import io.circe.Encoder
import io.circe.syntax._
def jsonPrinter[A: Encoder](obj: A): String = obj.asJson.noSpaces
Scala 的语法糖是什么:
Which is Scala's syntactic sugar for something like this:
def jsonPrinter[A](obj: A)(implicit encoder: Encoder[A]): String =
obj.asJson.noSpaces
这两个都会编译,您可以向它们传递具有隐式 Encoder
实例的任何类型的值.对于您的 MessageModel
,您可以使用 circe 的泛型派生,因为它是一个 case 类:
Both of these will compile, and you can pass them a value of any type that has an implicit Encoder
instance. For your MessageModel
specifically, you could use circe's generic derivation, since it's a case class:
scala> import io.circe.generic.auto._
import io.circe.generic.auto._
scala> case class MessageModel(time: Long, content: String)
defined class MessageModel
scala> val message = MessageModel(123, "Hello World")
message: MessageModel = MessageModel(123,Hello World)
scala> jsonPrinter(message)
res0: String = {"time":123,"content":"Hello World"}
请注意,如果没有 auto
导入,这将无法工作,它为任何成员也可编码的 case 类(或密封特征层次结构)提供 Encoder
实例.
Note that this wouldn't work without the auto
import, which is providing Encoder
instances for any case class (or sealed trait hierarchy) whose members are all also encodeable.
这篇关于circe 如何将泛型类型对象解析为 Json?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!