Libraries

kotlinx.serialization 1.2发布,JSON的高性能解析,值类的支持,文档的翻修等等

Read this post in other languages:
English, Français, 日本語, 한국어, Deutsch, Português do Brasil, Русский, Español

kotlinx.serialization 1.2已发布!我们跨平台序列化库的最新版本带来了多个改进——下面是重点:

1.2版还新增对 JSON 字段候选名称的支持,以及提供了一种新的实验方案,可以自动从 Kotlin 类中生成 Protobuf 的 schema,为此,我们期待您的反馈!

让我们一起探索新版本中的新增和变化! 如果您已经想清楚了,当然也可以直接跳到下面的升级说明!

开始使用 kotlinx.serialization 1.2!


Subscribe to Kotlin YouTube!

远超以往的 JSON 编解码

kotlinx.serialization最常用的功能是将 Kotlin 类编码为 JSON 字符串,以及将 JSON 字符串转换为 Kotlin 类,并且我们一直在努力提高其性能。

Parsing JSON with kotlinx.serialization: Up to 55 percent faster

1.2版彻底调整了 kotlinx.serialization 的内部结构,从而使核心功能的性能大大提高。我们已经重写了 JSON 解码器(负责将文本转换为 Kotlin 对象),以及对 JSON 编码器(负责将 Kotlin 对象转换为文本) 进行了深度优化。

Encoding JSON with kotlinx.serialization: Up to 339 percent faster

只需升级我们的库到最新版本,您就可以将平常编解码任务的速度提高到两倍。(正如您所见,我们的一些受新优化影响的内部基准测试,甚至超过了这个数字(200%)!)
通过这些更改,kotlinx.serialization达到(某些方面超越)了其他开箱即用的JSON 库相同的性能。哪怕是最简单的代码块也可以从该调整中受益:
要感受改进带来的明显变化,最好是让您的应用程序使用最新的库并进行基准测试。有关一些粗略的性能数字,您可以查看我们内部基准的 encoding 和 decoding,它们比较了 kotlinx.serialization的新旧版本。

值类和无符号数字类型的稳定JSON(反)序列化

Kotlin 1.5.0新增了两个令人兴奋的内容,分别是值类无符号整型,而kotlinx.serialization 1.2现在为其提供了最优先的JSON编解码支持。让我们深入了解。

对值类的支持

值类(之前称为内联类) 是一种以类型安全的方式封装另一种Kotlin类型(例如数字) 而又没有额外运行时开销的方案。这有助于您程序的语义和安全,而不会造成性能损失。
kotlinx.serialization内置的JSON序列化现在可用于值类。就像其他Kotlin类一样,我们只需用@Serializable注释值类
值类直接以其基础类型方式存储(以及序列化)。我们可以通过在可序列化的数据类中添加类型为值类的字段,并观察其输出来了解情况:
在上面的示例中,NamedColor值类Color视为基础类型( Int )。这意味着您可以最大程度享受Kotlin代码的类型安全性,同时仍能从类型序列化的简便中得益,而避免了不必要的装箱或嵌套。
我们仍在改进针对值类的编写,自定义序列化器的设计,并且目前仍处于实验阶段。您可以在GitHub的文档中查阅该主题的更多资料。

对无符号整型的支持

无符号整型是Kotlin标准库的补充,为非负数提供类型和运算。随着 Kotlin 1.5.0 的发布,下述无符号数字类型已可用:
  • UByte,其值范围从 0 到 255
  • UShort,其值范围从 0 到 65535
  • UInt,其值范围从 0 到 2^32 – 1
  • ULong,其值范围从 0 到 2^64 – 1
现在kotlinx.serialization的JSON编解码器直接支持这些类型。就像其他数字类型一样,无符号整型会以其纯数字形式(和调用.toString 输出一致)进行序列化,而不会被截断,换行或转换为带符号类型。
请注意,JSON 当前支持值类和无符号整型。在将来的版本中,我们还将直接集成 CBOR 和 Protobuf ——敬请期待!

如果您想紧跟最新版本的kotlinx.serialization和Kotlin编程语言,请通过该博客旁边的表格订阅Kotlin产品更新资讯

有关更多kotlinx.serialization中使用值类和无符号类型的详细信息,请查看GitHub上的文档

JSON 字段的支持候选名称

有时您需要解析名称不一但意义相同的JSON字段,例如需要保持向后兼容。通过新的@JsonNames注解,您现在可以为JSON字段指定候选名称,这些名称会在解析过程用到。
为了说明这一点,让我们看一个例子。假设服务器会根据版本向我们返回以下两个响应其一:
nametitle的意义相同,我们希望将它们映射到Kotlin类中的同一字段。通过新的@JsonNames注解,我们可以指定titlename键的候选值:

请注意与@SerialName注解的不同在于,这个注解(<0>@SerialName)允许您编解码时重命名字段,但不允许您指定候选值

请注意与@SerialName注解的不同在于,这个注解(<0>@SerialName)允许您编解码时重命名字段,但不允许您指定候选值

新的API文档

为了让您学习 kotlinx.serialization的过程舒适而有趣,我们试着提供了大量参考资料。其一是GitHub上的 Kotlin 序列化指南,当中提供了库功能的演示,并包括单独的示例,以便您能直观地了解每个功能。
另一个是 kotlinx.serialization 的 API 文档,我们已经对其进行了全面修订。基于 Kotlin 文档引擎 Dokka 的新版本,新的API 文档采取了新的响应式和现代化设计,以及易导航的标示。

Example of the new API docs, showing the JsonElement documentation

探索新的 kotlinx.serialization API 文档!

Protobuf: 从 Kotlin 类中生成 schema(试验中)

Protocol Buffers(Protobuf) 是Google创建的二进制序列化数据结构。 作为二进制格式,它比JSON或XML更节省空间,同时其结构与语言无关,您可以将其用于应用程序到应用程序间的通信。

借助kotlinx.serialization,您可以使用实验中的稳定多平台 Protobuf 序列化(使用 proto2 语义)。与其他格式一样,用@Serializable注解您的类,并调用内置的encode/decode方法:

将您的Kotlin类作为明确的来源(以及您可能用到的定制化), kotlinx.serialization 能够推断出数据二进制的schema,让Protobuf在多个Kotlin应用程序之间的通信简洁且方便。

kotlinx.serialization 1.2现在还包含试验性质的用于Protocol Buffers的schema生成器。它允许您从Kotlin数据类生成.proto文件,这些文件又可用于生成其他语言(包括Python,C ++和TypeScript)的传输schema形式。

有关开始使用新的 schema 生成器的说明,请参阅文档中的相应说明。

一旦生成.proto文件后,您可以将其存储在仓库中,并通过它来生成Kotlin类在其他语言的表示形式。我们希望能让您更轻松地将kotlinx.serialization集成的Protobuf应用到多语言应用程序中,而无需丧失在Kotlin源码中直接管理schemas的便利。
因为这是 Protobuf schema 生成器的首个迭代,所以我们很大程度上依赖您的反馈。请尝试一下,并通过 GitHub 问题跟踪器告知我们您的用例,如何管理实体类和.proto文件,以及遇到的所有问题和期待的功能 。
使用 schema 生成器时,请牢记有一些限制。根据经验,如果可以通过kotlinx.serialization的 protobuf 实现来序列化 Kotlin 类,则 schema 生成器同样支持它。这也意味着限制同样适用。需要注意以下几点:
  • Kotlin的类和属性名需要符合protobuf规范,并且不得包含非法字符。
  • Kotlin的可空性没有反映在schema中(因为proto2没有语义)。根据Kotlin的属性是否定义了默认值,使用protocol buffers提供的可选字段
  • Kotlin默认值未包含在schema中。(这意味着您必须确保不同语言实现中默认值设置的一致性。)

开始使用 kotlinx.serialization 1.2!

说明到此结束! 如果您准备享受更快的JSON编解码,支持Kotlin 1.5添加的类型系统,生Protobuf schema成等,那么就该升级了!
如果您已经在使用kotlinx.serialization了,那么很快捷就能升级到1.2版本(而如果您以前没有尝试过kotlinx.serialization,那么现在开始是个不错的选择!)。首先,更新您build.gradle.kts文件中的plugins块:

然后,更新您的dependencies和运行时库,包括您要在应用程序中使用的格式:

更多的观看及阅读材料

如果您遇到任何问题

订阅 Kotlin 的 YouTube! Happy (de)serializing!

特别感谢由来自 Kotlin 社区的 黄智聪 (pye52) 为本篇博文提供中文译文。

Discover more