proto3中如何通过字段名获取字段对象 替代proto2的MutableExtension功能
Proto2迁Proto3替代MutableExtension的实现方案
Proto3官方废弃了extensions特性,你想要保留Foo::b形式的调用方式,有两种可行方案:
方案1:基于Proto反射API实现
Proto3原生保留了完整的反射能力,可以通过字段描述符直接获取可变对象,不需要修改现有.proto定义:
实现步骤
- 先获取
Foo的描述符,找到对应字段b的FieldDescriptor - 调用
Message的Reflection接口获取可变对象
代码示例
// 可以预先定义常量替代原来的Foo::b标识 const google::protobuf::FieldDescriptor* Foo_b = Foo::descriptor()->FindFieldByName("b"); // 调用逻辑和原来几乎一致 Foo foo; Foo::Bar* b_val = dynamic_cast<Foo::Bar*>(foo.GetReflection()->MutableMessage(&foo, Foo_b));
方案2:手动封装适配层(兼容性最优)
如果不想修改原有业务代码的调用写法,可以给Foo类扩展一个适配方法,完全复用原来的MutableExtension调用格式:
适配代码
// 在你的公共头文件里添加如下适配逻辑 enum FooExtensionId { FOO_B = 1 }; const auto Foo_b = FOO_B; // 重载Foo的MutableExtension方法 Foo::Bar* MutableExtension(Foo& foo, FooExtensionId id) { switch(id) { case FOO_B: return foo.mutable_b(); default: assert(false); return nullptr; } }
业务调用和原来完全一致:
Foo foo; Foo::Bar* b_val = MutableExtension(foo, Foo_b);
小提示:你示例里的
unint32是笔误,正确写法是uint32,迁移的时候注意修正避免编译报错。
内容的提问来源于stack exchange,提问作者Mihir
相关产品推荐
相关产品推荐

