Hacker News 中文摘要

RSS订阅

JSON 的新实验性 Go API -- A new experimental Go API for JSON

文章摘要

Go 1.25引入了新的实验性encoding/json/v2encoding/json/jsontext包,旨在改进和修复现有encoding/json包的不足。这些新包提供了长期期待的功能优化,但目前仍处于实验阶段,未来可能会有API变动。JSON作为互联网上最流行的数据交换格式,Go对其支持的需求日益增长,新版本将更好地满足用户需求。

文章总结

标题:Go语言中的新实验性JSON API

主要内容:

Go语言团队在2025年9月9日发布了一篇关于Go 1.25中新的实验性encoding/json/v2encoding/json/jsontext包的博客文章。这些新包旨在解决现有encoding/json包中的一些长期存在的问题,并引入了一些期待已久的改进和修复。

现有encoding/json包的问题:

  1. 行为缺陷

    • JSON语法处理不精确:现有包接受无效的UTF-8编码和重复的JSON对象成员名,而最新的JSON标准(RFC 8259)要求UTF-8编码有效,并且重复成员名可能导致安全问题。
    • 切片和映射的nil值泄漏:现有包将nil切片和映射序列化为JSON的null,而大多数用户更希望它们被序列化为空的JSON数组或对象。
    • 大小写不敏感的解析:现有包在解析JSON对象成员名时使用大小写不敏感的匹配,这可能导致安全漏洞和性能问题。
    • 方法调用不一致:由于实现细节,MarshalJSON方法在指针接收器上的调用不一致,且无法修复,因为太多应用程序依赖当前行为。
  2. API缺陷

    • io.Reader正确反序列化较为困难,且无法拒绝输入末尾的无效数据。
    • 选项可以设置在EncoderDecoder类型上,但无法与MarshalUnmarshal函数一起使用。
    • CompactIndentHTMLEscape函数写入bytes.Buffer,而不是更灵活的[]byteio.Writer
  3. 性能限制

    • MarshalJSONUnmarshalJSON接口方法强制分配内存,且需要重新解析JSON值。
    • 缺乏流式处理能力,EncoderDecoder类型在内存中缓冲整个JSON值。

新包的设计与改进:

为了解决这些问题,Go团队决定引入新的encoding/json/v2包,而不是直接修复现有包。新包的设计基于encoding/json/jsontext包,后者专注于JSON的语法处理,而v2包则在此基础上增加了语义功能。

encoding/json/v2的主要改进:

  1. 行为改进

    • 报告无效UTF-8和重复JSON对象成员名的错误。
    • 将nil切片和映射序列化为空的JSON数组或对象。
    • 使用大小写敏感的匹配解析JSON对象成员名。
    • 重新定义omitempty标签选项,以省略编码为“空”JSON值的字段。
  2. 性能优化

    • Unmarshal性能显著提升,某些情况下比v1快10倍。
    • 引入MarshalJSONToUnmarshalJSONFrom接口方法,支持流式处理JSON。
  3. API灵活性

    • 允许调用者为任意类型指定自定义的JSON表示。
    • 支持通过选项配置MarshalUnmarshal的行为。

实验与未来计划:

新包目前处于实验阶段,用户可以通过设置GOEXPERIMENT=jsonv2环境变量或使用goexperiment.jsonv2构建标签来使用。Go团队鼓励用户测试新包并反馈问题,以决定是否将其正式纳入标准库。

总结:

encoding/json/v2包旨在解决现有包中的问题,并提供更灵活、更高效的JSON处理方式。虽然新包目前处于实验阶段,但其设计和实现已经得到了广泛的生产环境验证。用户可以通过测试和反馈帮助决定新包的未来发展方向。

评论总结

  1. 关于JSON解析器的性能与设计

    • 评论1提到了一份关于Go语言中Sonic、Standard JSON和JSON v2的性能基准测试分析,但没有给出具体结论。
      • 引用:"Benchmark Analysis: Sonic vs Standard JSON vs JSON v2 in Go"
    • 评论3批评了Go的encoding/json包的设计,认为其从一开始就设计不佳,而非用户需求的变化导致。
      • 引用:"It was badly designed from the start - it's not just that people's json needs (which hardly changed) outgrew it."
  2. 关于JSON中null的处理

    • 评论2指出,大多数语言的JSON解析器和生成器在处理null时存在问题,建议使用特殊值来表示“JSON null”。
      • 引用:"Most JSON parsers and emitters in most languages should use a special value for 'JSON null'."
      • 引用:"Ironically, JavaScript with its hilarious null and undefined does not have this problem."
  3. 对Go JSON库的简要概述

    • 评论4询问了Go JSON库的高级概述,提到它支持将Go原生结构编码为JSON,但可能存在设计问题。
      • 引用:"It looks like Go JSON lib has support to encode native go structures in JSON, which is cool, but maybe it was bad, which is not as cool."

总结:评论主要围绕Go语言中JSON解析器的性能、设计缺陷以及null处理问题展开。一方面,有评论指出encoding/json包设计不佳;另一方面,也有评论建议改进null的处理方式。此外,还有评论对Go JSON库的功能进行了简要概述,并对其设计提出了疑问。