这是我想要做的事情
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 ^
我有点理解为什么会这样,但是有办法解决它吗?
谢谢
答案 0 :(得分:7)
circe中的编码和解码由类型类提供,这意味着如果要编码(或解码)a,则必须能够在编译时证明您具有A
的类型类实例。类型A
的值。
这意味着当你写这样的东西时:
import io.circe.syntax._
def jsonPrinter[A](obj: A): String = obj.asJson.noSpaces
您无法提供有关A
的足够信息,以便能够打印该类型的值。您可以使用上下文绑定来解决此问题:
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
个实例,其成员都是可编码的。