给出以下案例类LogMessage
:
import io.circe.{Decoder, Encoder}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import enumeratum.{CirceEnum, Enum, EnumEntry}
import io.circe.syntax._
sealed trait LogLevel extends EnumEntry
object LogLevel extends Enum[LogLevel] with CirceEnum[LogLevel] {
val values = findValues
case object Warning extends LogLevel
case object Error extends LogLevel
case object Info extends LogLevel
case object Success extends LogLevel
}
object LogMessage {
implicit val logMessageDecoder: Decoder[LogMessage] = deriveDecoder[LogMessage]
implicit val logMessageEncoder: Encoder[LogMessage] = deriveEncoder[LogMessage]
}
case class LogMessage(level: LogLevel, text: String, args: List[String], date: Long)
case class MyClass[A](obj: A)(implicit encoder: Encoder[A]) {
def message1: String = obj.asJson.toString
def message2: Option[String] = obj.asJson.asString
}
为什么这样做:
val x = MyClass(LogMessage(LogLevel.Info, "test notification", Nil, 1550218866571))
x.message1 // {\n "level" : "Info",\n "text" : "test notification",\n "args" : [\n ],\n "date" : 1550218866571\n}
但这不是:
x.message2 // None
这里是指向Scastie的链接,存在以下问题:link。
答案 0 :(得分:3)
大约Json
有六个asX
方法,它们对应于JSON中的六个数据类型。例如,如果Json
实例x
表示一个JSON布尔值,则x.asBoolean
将返回一个包含值的Some
的{{1}},但是如果{{1 }}是JSON字符串,数组,对象,数字或null,Boolean
将为空。
在这种情况下,您看到x
返回x.asBoolean
是因为您是在代表JSON对象而不是JSON字符串的.asString
值上调用它的。
None
上的Json
方法是完全不同的:它是通用的Scala / Java toString
,在Json
的情况下,它实现为toString
。我不确定您要在这里做什么,但是通常我建议避免使用Json
-如果要序列化.spaces2
值,最好使用打印机或打印使格式化选项更明确的方法(例如toString
,io.circe.Json
等)。
(出于价值考虑,我对noSpaces
上的spaces2
,asString
等方法的命名并不完全满意。通常使用“ as”在用于编码或解码的方法名称中,这并不完全是这些情况下发生的事情,但是它足够接近,以至于我从来没有想过要找到更好的选择。)