Chr*_*ris 3 c++ protocol-buffers
假设我有一个 proto 定义为:
MyProto {
optional MyWrapper wrapper = 1;
}
Run Code Online (Sandbox Code Playgroud)
在哪里:
MyWrapper {
repeated int32 data = 1;
}
Run Code Online (Sandbox Code Playgroud)
当我调用MergeFromString的两个文本规范时MyProto,包装器内重复字段的两个版本被连接(一个附加到另一个。)我真的希望它们被覆盖。文档MergeFromString说:
当我们在 |serialized| 中找到一个字段时 此消息中已经存在:
- 如果它是一个“重复”字段,我们将附加到列表的末尾。
- 否则,如果它是标量,我们将覆盖我们的字段。
- 否则,(它是一个非重复的组合),我们递归地合并到现有的组合中。
显然,对于包装器,我们谈论的是第三种情况。所以我们递归地合并,在下一次循环中,我们看到一个重复的字段,值被附加到目标。所以我明白为什么会这样了。
将此与以下规范进行比较MergeFrom:
此方法将指定消息的内容合并到当前消息中。指定消息中设置的单个字段会覆盖当前消息中的相应字段。附加重复的字段。单个子消息和组被递归合并。
在这种情况下,包装器字段不是单一字段,包装器不会被覆盖吗?
所以我的问题是双重的,
1)这是不一致的,还是我误解了什么?
2)如何在调用时获得所需的覆盖行为而不是合并重复字段MergeFromString?
小智 5
对于您问题的第一部分,您MergeFrom引用的规范在技术上是正确的,尽管措辞有点混乱。它说“单一字段”被覆盖,但“单一子消息”被递归合并,并且您的包装器将被视为单一子消息。
要获得您想要的行为,您应该能够使用FieldMaskUtil。特别是您可以调用FieldMaskUtil::MergeMessageTo(...)并传递一个MergeOptions配置来替换重复的字段而不是连接它们。为此,您首先必须从它们的文本格式表示中解析这两条消息。