我想采用 jsoniter,一个很棒的 Scala JSON 序列化器库。 我正在使用 Scala 3。
唯一的障碍是我需要序列化这个:
Map[String, Any]
其中
Any
是一个类,其中 given 编解码器可用,例如String
、Date
、Int
、....
也许解决方案可以编写自定义编解码器,并且我可能需要使用反射。 但我不知道如何开始。我已经看到了
Map[String, Int]
生成的编解码器。
或者也许使用另一个 JSON scala 解析器库会更容易。
我知道 json4s 可以用 Scala 2 处理它,但是在 Scala 3 中它有问题。它使用反射。
一种方法是将类型类作为类型绑定传递:
given map [A: JsonValueCodec]: JsonValueCodec[Map[String, A]] =
JsonCodecMaker.make
// the same as
given map [A](using JsonaValueCodec[A]): JsonValueCodec[Map[String, A]] =
JsonCodecMaker.make
限制是 Jsoniter Scala 仅提供半自动推导,并且
JsonaValueCodec
的值仅由库提供 JsonCodecMaker.make
(无 given
:String
、Int
、Map
s、List
s)等,OOTB),所以如果您需要 JsonValueCodec[Map[String, Int]]
和上面的 given
,您还必须另外做:
given JsonValueCodec[Int] = JsonCodecMaker.make
summon[JsonValueCodec[Map[String, Int]]]
因为有点不方便,你也可以使用
inline
让宏在编译时解决问题:
inline given [A]: JsonValueCodec[Map[String, A]] = JsonCodecMaker.make
summon[JsonValueCodec[Map[String, Int]]]
事实上,我们可以使用 Jsoniter 引入自动推导:
// allows overriding config with:
// inline given config: CodecMakerConfig = CodecMakerConfig.addSomeOption
// summon[
inline given [A](
using inline config: CodecMakerConfig = CodecMakerConfig
): JsonValueCodec[A] = JsonCodecMaker.make(config)
summon[JsonValueCodec[Map[String, Int]]]
但是,我会小心:Jsoniter 是在考虑半自动派生的情况下构建的(这样您就不会创建中间编解码器,只是为了组合它们并施加开销),并且像这样使用它不受官方支持。它可能会造成一些性能损失(甚至可能是一些错误)。
但它引用很方便,所以如果您正在测试代码并对它进行基准测试,您应该注意到发生的任何问题。