【问题标题】:How does circe parse a generic type object to Json?circe如何将泛型类型对象解析为Json?
【发布时间】:2016-10-22 02:39:11
【问题描述】:

这就是我想要做的事情

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 ^

我有点理解为什么会发生这种情况,但是有没有办法解决它?

谢谢

【问题讨论】:

  • 废话,刚刚发现如果我这样做: def jsonParser[A: Encoder] (obj: A) : String = ...,它的工作原理!

标签: scala


【解决方案1】:

circe 中的编码和解码由类型类提供,这意味着如果要编码(或解码)值输入A

这意味着当你写这样的东西时:

import io.circe.syntax._

def jsonPrinter[A](obj: A): String = obj.asJson.noSpaces

您没有提供有关 A 的足够信息,因此 circe 无法打印该类型的值。您可以使用上下文绑定来解决此问题:

import io.circe.Encoder
import io.circe.syntax._

def jsonPrinter[A: Encoder](obj: A): String = obj.asJson.noSpaces

对于这样的事情,Scala 的语法糖是什么:

def jsonPrinter[A](obj: A)(implicit encoder: Encoder[A]): String =
  obj.asJson.noSpaces

这两个都可以编译,你可以给它们传递一个具有隐式Encoder 实例的任何类型的值。对于您的MessageModel,您可以使用 circe 的泛型派生,因为它是一个案例类:

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 导入,这将无法工作,它为任何成员都可编码的案例类(或密封特征层次结构)提供 Encoder 实例。

【讨论】:

  • 是的,我只是在你回答之前几秒钟就想通了,但你是对的。谢谢
猜你喜欢
  • 2022-11-12
  • 1970-01-01
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多