更简洁的 Preserves 二进制语法

更简洁的 Preserves 二进制语法

💡 原文英文,约300词,阅读约需1分钟。
📝

内容提要

Preserves规范更新至0.990.0版,作者认为1.0候选版临近。主要变化是简化二进制语法:移除“短”和“中”两种SignedInteger表示,所有SignedInteger统一用0xB0标签;Float和Double改用0x87标签加长度编码,取代固定标签0x82和0x83,为未来支持其他IEEE754格式铺路。文中还以参考卡形式列出各类型值的二进制编码规则及varint编码方式。

🔎

延伸解读

二进制语法简化的取舍

0.990.0 版移除了 SignedInteger 的“短”和“中”两种表示,统一用 0xB0 标签加 varint 长度和整数字节。作者认为这些旧表示“不划算”,简化后编码规则更一致,但可能增加小整数的编码长度。读者需注意:这是规范层面的精简,实际实现需同步调整解析逻辑。

Float/Double 编码的扩展性

Float 和 Double 从固定标签 0x82、0x83 改为 0x87 加长度字节(0x04 或 0x08),为未来支持其他 IEEE754 格式(如半精度)留出空间。这种设计用少量额外字节换取格式扩展性,但解析时需先读长度再决定如何解释后续字节。

varint 与长度前缀的统一

参考卡显示,SignedInteger、String、ByteString、Symbol 等类型都使用 varint 编码长度或整数字节数。varint 对小于 128 的值用单字节,更大值用多字节。这种统一减少了标签种类,但要求实现者正确实现 varint 的变长解码,否则会影响所有带长度前缀的类型。

❓

Q&A

Preserves 0.990.0 版本对二进制语法做了哪些主要简化?

主要简化包括:移除了 SignedInteger 的“短”和“中”两种表示(标签 0x9x/0xAx),所有 SignedInteger 统一使用标签 0xB0;Float 和 Double 改用标签 0x87 加长度编码,取代了原来的固定标签 0x82 和 0x83。

为什么 Preserves 要移除 SignedInteger 的短和中表示?

文章指出这些表示“没有发挥应有的作用”(weren't pulling their weight),因此被移除,所有 SignedInteger 现在统一用 0xB0 标签编码。

Preserves 中 Float 和 Double 的二进制编码现在是什么?

Float 编码为 [0x87, 0x04] 后跟 binary32 值;Double 编码为 [0x87, 0x08] 后跟 binary64 值。两者都使用标签 0x87 加长度,取代了旧的固定标签 0x82 和 0x83。

Preserves 二进制语法中 varint 是如何编码的?

varint 编码规则:如果 v < 128,则编码为单字节 [v];如果 v ≥ 128,则编码为 [(v & 0x7F) + 128] 后跟 varint(v >> 7)。

Preserves 中 String 和 Symbol 的二进制编码有什么区别?

String 使用标签 0xB1,后跟 varint 编码的 UTF-8 字节长度和 UTF-8 字节;Symbol 使用标签 0xB3,同样后跟 varint 编码的 UTF-8 字节长度和 UTF-8 字节。两者结构相同,仅标签不同。

Preserves 中如何编码一个字典(Dictionary)?

字典编码为 [0xB7] 后跟每个键值对的编码(«K_1» «V_1» ... «K_m» «V_m»),最后以 [0x84] 结束。

🏷️

标签

➡️

继续阅读