【发布时间】:2019-06-21 23:49:47
【问题描述】:
我正在使用 circe 序列化/反序列化一些相当大的模型,其中每个叶字段都是强类型(例如 case class FirstName(value: String) extends AnyVal)。
Encoder 或 Decoder 的隐式解析/派生速度很慢。
我有自己的编解码器,为此我添加了一些额外的 Encoder 和 Decoder 实例:
trait JsonCodec extends AutoDerivation {
// ...
}
使用以下方法帮助解码:
package json extends JsonCodec {
implicit class StringExtensions(val jsonString: String) extends AnyVal {
def decodeAs[T](implicit decoder: Decoder[T]): T =
// ...
}
}
问题是每次我调用decodeAs,它都会隐式派生一个Decoder,这会导致编译时间大幅增加。
有什么方法可以(通常)缓存隐式,使其只生成一次Decoder?
【问题讨论】:
-
我不确定您的
StringExtensionsclass 是否有可能。但是,每当您调用decodeAs方法 时,您可以先执行此操作:implicit val tDecoder: Decoder[T] = derieveDecoder(将T更改为您自己的类型)。这样,所有对decodeAs[T]的调用都将使用val,而不是派生一个新的解码器。 注意:如果您的模型包含许多嵌套类型,请以相反的顺序为每个类型创建解码器。 -
我不认为 Luis 的想法可以节省任何东西,因为编译器仍然需要为每个
implicit val生成所有这些Decoders。我能想到的唯一方法是将您的类型的所有这些解码器作为implicit vals 放在一些全球已知的静态位置,例如您的json包对象本身。那么每次只能有一个这样的implicit val,并且编译器可以在每次需要这样的Decoder时使用这些曾经派生的值(假设您将import它们放入您的上下文中)。
标签: scala implicit shapeless circe