如果删除 protobuf 上的字段会发生什么?

What happened if you delete a field on protobuf?

示例:

message Foo {
  ...
  string AccountToken = 3
  string BusinessToken = 4
  ...
}

由于项目所有者希望弃用这 2 个字段,我是否可以通过删除并重新生成代码然后删除所有引用来安全地删除这 2 个字段?

是的,您可以删除它们。如果另一方仍然发送这些字段,您的新代码将忽略它们。但就像@LeiYang 提到的那样,使用已弃用的语法。如果开发人员后来将索引 3 或 4 用于不同的字段,事情就会出错。特别是如果它不是同一类型,在你的情况下是字符串。

重要的是要了解协议缓冲区的序列化是通过这些标签实现的。 删除它们可能会在反序列化过程中导致意外行为

因此请注意,删除这两个字段而不使用 reserved 关键字会破坏向后和向前兼容性。如果您的架构的更高版本使用 3 和 4 作为标记,而您的代码的某些旧版本仍然使用这些标记作为 AccountTokenBusinessToken,您将遇到意外行为。

为了安全地删除这些字段,您可以这样做:

message Foo {
  reserved 3, 4;
  ...
}

并且您可以选择保留字段名称,以便模式不使用 AccountTokenBusinessToken 字段的名称,因此不会与您的代码冲突(例如:您返回旧版本的代码和一个名为 business_token 的字段,但它与新模式不再具有相同的含义)。为此,您可以这样做:

message Foo {
  reserved 3, 4;
  reserved "business_token", "account_token"; // assuming they are called like this
  ...
}

通过执行第一步和可选的第二步,您可以确保完全兼容(向后和向前)。