有一个“设置”方法,但它被称为setWithCaveats()
:
destListBuilder.setWithCaveats(index, sourceStructReader)
这是为了让您知道设置结构列表的元素存在一些晦涩难懂的问题。问题源于结构列表不像您所期望的那样表示为指针列表,而是它们是一系列“扁平化”的连续结构,大小相同。这意味着列表中所有结构的空间都是在初始化列表时分配的。因此,当您调用 时setWithCaveats()
,目标空间之前已经分配,并且您正在将源结构复制到该空间中。
面对不同的版本,这会带来一个问题:源结构可能是使用更新版本的协议构建的,其中定义了额外的字段。在这种情况下,它实际上可能比预期的要大。但是,目标空间已经根据您编译的协议版本分配。所以,太小了!不幸的是,我们别无选择,只能丢弃我们不知道的新定义的字段。因此,数据可能会丢失。
当然,可能是在您的应用程序中,您知道结构值不是来自较新的版本,或者您不在乎是否丢失了您不知道的字段。在这种情况下,setWithCaveats()
会做你想做的事。
如果您想小心保留未知字段,您可能需要查看方法capnp::Orphanage::newOrphanConcat()
。此方法可以将结构读取器列表的列表连接到单个列表中,这样不会丢失任何数据——分配目标列表的每个结构的大小等于所有输入结构的最大值。
auto orphanage = Orphanage::getForMessageContaining(builder);
auto orphan = orphanage.newOrphanConcat({list1Reader, list2Reader});
builder.adoptListField(kj::mv(orphan));