vault backup: 2026-05-07 19:06:05

This commit is contained in:
2026-05-07 19:06:05 +08:00
parent 80a14ef618
commit 50a67ea37b
+4 -4
View File
@@ -91,8 +91,8 @@ D. 旧客户端把该字段当作空字符串处理
A. `oneof` 可以修饰 `repeated` 类型的字段,方便存储一组互斥值
B. Proto3 中 `oneof` 所有变体共享同一个零值 `NONE(0)`,所以反序列化时无法区分哪个变体被设置过
C. 新增 oneof 变体会破坏旧客户端的兼容性
D. oneof 中的每个成员必须使用不同的字段编号,且编号不能跨 oneof 组共用
C. Proto3 会为 oneof 自动生成 IsXXX() setter 方法以支持精确的状态判断
D. oneof 中的成员编号必须跨不同 oneof 组全局唯一
> [!tip]- Q3 答案
> **B — oneof 零值为 NONE(0),无法区分未设置状态**
@@ -103,8 +103,8 @@ D. oneof 中的每个成员必须使用不同的字段编号,且编号不能
> **逐项分析:**
> - ❌ A:`oneof` **不能**加 `repeated` 修饰符,因为 multiple 值和 oneof 互斥语义矛盾
> - ✅ B:正确。Proto3 没有 Optional 概念,当 all fields 都等于其默认值时,你无法知道用户到底传了 `"none"` 还是没传
> - ❌ C:新增 oneof 变体是安全的——旧客户端会把它当成未知编号字段忽略
> - ❌ D:oneof 内的成员只需在自己的 oneof 内唯一,不同 oneof 之间可以重用编号
> - ❌ C:Proto3 **不会**为 oneof 自动生成任何 `IsXXX()` 方法。这正是 Proto3 oneof 的核心痛点——你无法通过 API 判断哪个变体被设置过(因为当所有值都等于默认值时,语义上就是不可区分的)。如果需要区分"未设置"和"设置为空值",必须使用 Well-Known Types 包装器。
> - ❌ D:**错误**。Protobuf 规范只要求字段编号在同一个 oneof **内部**唯一,不同 oneof 之间可以重用编号(proto 的二进制编码只看 `(field_number, wire_type)`,不同 oneof 之间不会产生冲突)
>
> **如果需要精确表达"可选"**,推荐使用 Well-Known Types 中的 `StringValue` 包装:
> ```proto