circe 如何将泛型类型对象解析为 Json? [英] How does circe parse a generic type object to Json?

查看:51
本文介绍了circe 如何将泛型类型对象解析为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆