If an existing message type no longer meets all your needs – for example, you'd like the message format to have an extra field – but you'd still like to use code created with the old format, don't worry! It's very simple to update message types without breaking any of your existing code. Just remember the following rules:
如果一个已经存在的message类型不再满足你所有的需求 - 举个例子,你想让该消息类型拥有一个额外字段 - 但是你还想继续使用旧格式创建出来的代码,别担心!更新消息类型是很简单的,且无需破坏任何现有代码。只需记住以下这些规则:
Don't change the field numbers for any existing fields.
不要修改任何已存在字段的字段值。If you add new fields, any messages serialized by code using your "old" message format can still be parsed by your new generated code. You should keep in mind the default values for these elements so that new code can properly interact with messages generated by old code. Similarly, messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing. See the Unknown Fields section for details.
如果你添加新的字段,任何被使用“旧”消息格式的代码序列化的消息,仍然可以被生成的代码所解析。你应该记住这些元素的默认值,以便新代码能够正确的和旧代码生成的message进行交互。类似的,新代码创建的message也可以被你的旧代码所解析:解析时旧二进制仅仅是忽略新字段。参阅[未知字段]((https://developers.google.com/protocol-buffers/docs/proto3#unknowns)章节获取详细信息。Fields can be removed, as long as the field number is not used again in your updated message type. You may want to rename the field instead, perhaps adding the prefix "OBSOLETE_", or make the field number reserved, so that future users of your
.proto
can't accidentally reuse the number.
只要字段数字不会在你更新后的message类型中被再次使用,字段是可以被删除的。你可能希望重命名该字段,或许添加"OBSOLETE_"前缀,或者将字段值标记为保留,以便后来的.proto
文件使用者不能一不小心重用这个数字。int32
,uint32
,int64
,uint64
, andbool
are all compatible – this means you can change a field from one of these types to another without breaking forwards- or backwards-compatibility. If a number is parsed from the wire which doesn't fit in the corresponding type, you will get the same effect as if you had cast the number to that type in C++ (for example, if a 64-bit number is read as an int32, it will be truncated to 32 bits).
int32
,uint32
,int64
,uint64
, 和bool
都是可兼容的 - 这意味着你可以从其中一种类型修改成其他类型,而不会破坏其向前或向后的兼容性。sint32
andsint64
are compatible with each other but are not compatible with the other integer types.
sint32
和sint64
是相互兼容的,但是不能和其他整型类型兼容。string
andbytes
are compatible as long as the bytes are valid UTF-8.
只要是有效的UTF-8字节string
andbytes
是兼容的。Embedded messages are compatible with
bytes
if the bytes contain an encoded version of the message.
内嵌message和bytes
是兼容的,如果字节中包含了该message一个编码后的版本。fixed32
is compatible withsfixed32
, andfixed64
withsfixed64
.
fixed32
和sfixed32
是兼容的,fixed64
和sfixed64
是兼容的。For
string
,bytes
, and message fields, singular fields are compatible withrepeated
fields. Given serialized data of a repeated field as input, clients that expect this field to be singular will take the last input value if it's a primitive type field or merge all input elements if it's a message type field. Note that this is not generally safe for numeric types, including bools and enums. Repeated fields of numeric types can be serialized in the packed format, which will not be parsed correctly when a singular field is expected.
对于string
,bytes
,和message字段,单一字段和repeated
字段兼容。给定的重复字段的序列化后的数据作为输入,而客户端期望这个字段是单一数据,那么如果这是一个原始类型字段则只取最后一条输入值,或者如果这是一个message类型字段就合并所有输入元素。注意这个对于数字类型并不是普遍安全的,包括布尔和枚举。数字类型的重复字段可以被序列化为packed格式中,而当需要单一字段时就不会正确解析。enum
is compatible withint32
,uint32
,int64
, anduint64
in terms of wire format (note that values will be truncated if they don't fit). However be aware that client code may treat them differently when the message is deserialized: for example, unrecognized proto3enum
types will be preserved in the message, but how this is represented when the message is deserialized is language-dependent. Int fields always just preserve their value.
在线路格式方面enum
与int32
,uint32
、int64
及uint64
兼容(如果他们不合适数据将会被截断)。然而要知道当message被序列化时客户端状态码必须区别对待它们:举个例子,未识别的proto3enum
类型会被保留在message中,但是message反序列化时如何保存取决于语言。对于整型字段总是只保存它们的值。Changing a single
optional
field or extension into a member of a newoneof
is safe and binary compatible. Moving multiple fields into a newoneof
may be safe if you are sure that no code sets more than one at a time. Moving any fields into an existingoneof
is not safe. Likewise, changing a single fieldoneof
to anoptional
field or extension is safe.
修改一个单一optional
字段或者扩展为oneof
新的一员是安全的,且和binary兼容。如果你能保证没有代码一次设置超过一个,将多个字段修改为新的oneof
可能是安全的。将任何字段修改为一个已经存在的oneof
是不安全的。同样地,修改一个单一字段oneof
为optional
字段或者扩展是安全。