假设我将proto定义为:
MyProto {
optional MyWrapper wrapper = 1;
}
其中:
MyWrapper {
repeated int32 data = 1;
}
当我在MergeFromString
的两个文本规范上调用MyProto
时,包装器中重复字段的两个版本被连接(一个附加到另一个。)我真的希望它们被覆盖代替。 MergeFromString
的文档说:
当我们在| serialized |中找到一个字段时这已经存在于此 消息:
- 如果是"重复"字段,我们附加到列表的末尾。
- 否则,如果它是标量,我们会覆盖我们的字段。
- 否则,(它是一个非重复的复合词),我们递归合并 进入现有的复合材料。
显然,使用包装器,我们正在讨论第三种情况。所以我们递归合并,在下一次复飞时,我们看到一个重复的字段,并将值附加到目标。所以我明白为什么会这样。
将此与MergeFrom
的规范进行比较:
此方法将指定消息的内容合并到 当前的消息。在指定消息中设置的奇异字段 覆盖当前消息中的相应字段。重复 字段被追加。奇异的子消息和组是递归的 合并。
在这种情况下,包装字段不是单个字段,并且不会覆盖包装器吗?
所以我的问题是双重的,
1)这是不一致的,还是我误解了什么?
2)当我致电MergeFromString
时,如何获得所需的覆盖行为,而不是合并重复的字段?
答案 0 :(得分:2)
对于问题的第一部分,您引用的MergeFrom
规范在技术上是正确的,尽管措辞有些令人困惑。它说“奇异字段”被覆盖但是“单个子消息”被递归合并,并且你的包装器将被认为是一个单一的子
消息。
要获得所需的行为,您应该可以使用FieldMaskUtil。特别是,您可以调用FieldMaskUtil::MergeMessageTo(...)
并传递MergeOptions
配置为替换重复字段而不是连接它们。为此,您首先必须从文本格式表示中解析这两条消息。