如何使用 jsoniter 序列化 Map[String, Any]

问题描述 投票:0回答:1

我想采用 jsoniter,一个很棒的 Scala JSON 序列化器库。 我正在使用 Scala 3。

唯一的障碍是我需要序列化这个:

Map[String, Any]

其中

Any
是一个类,其中 given 编解码器可用,例如
String
Date
Int
、....

也许解决方案可以编写自定义编解码器,并且我可能需要使用反射。 但我不知道如何开始。我已经看到了

Map[String, Int]
生成的编解码器。

或者也许使用另一个 JSON scala 解析器库会更容易。

我知道 json4s 可以用 Scala 2 处理它,但是在 Scala 3 中它有问题。它使用反射。

json scala parsing scala-3 jsoniter-scala
1个回答
0
投票

一种方法是将类型类作为类型绑定传递:

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 是在考虑半自动派生的情况下构建的(这样您就不会创建中间编解码器,只是为了组合它们并施加开销),并且像这样使用它不受官方支持。它可能会造成一些性能损失(甚至可能是一些错误)。

但它引用很方便,所以如果您正在测试代码并对它进行基准测试,您应该注意到发生的任何问题。

© www.soinside.com 2019 - 2024. All rights reserved.