【Protobuf速成指南】Any类型的使用

2.2 Any类型的使用

 本系列文章将通过对通讯录项目的不断完善,带大家由浅入深的学习Protobuf的使用。这是Contacts的2.2版本,在这篇文章中将带大家学习Protobuf的 Any 类型语法,并将其用到我们的项目中

一、基本认识

 Protobuf中的Any类型可以理解为泛型类型,它可以存储任何消息类型的字段(int, char等类型必须先封装成消息类型)。Any类型字段也可以用 Repeated 修饰。

 Any类型定义在 any.proto 文件中。可以在 /usr/local 路径下可以找到。我在安装的时候将 lib 和 include 统一配置到 /usr/local/protobuf 文件中。如果没有配置的话,lib和include是分散的。

image-20230608113140552

二、使用需知

①头文件的包含:

image-20230608113635069

使用Any字段前首先需要包含头文件,先前做过的环境变量配置如上

  • 因此可以如下包含头文件

    image-20230608113832834

  • 引入 any.proto 文件

    image-20230608115147745

②命名空间:gooole::protobuf

image-20230608114030513

三、Any字段的使用

①修改proto文件

我们先创建一个Address消息字段,并在 PeopleInfo 消息中用Any类型字段接收

syntax = "proto3";
package contact2;

import "google/protobuf/any.proto";

message Address{
    string home = 1;
    string company = 2;
}

message PeopleInfo{
    string name = 1;
    int32 age = 2;
    message Phone{   
        string number = 1;
        enum PhoneType{
            MOBILE = 0;
            FIXED = 1;
        }
        PhoneType type = 2;
    }
    repeated Phone phone = 3;
    google.protobuf.Any addr = 4;
}

message Contact{
    repeated PeopleInfo contact = 1;
}

② Any相关函数

编译 .proto 文件后,我们来分析 contacts.pb.h 文件中对于Any类型更新的代码片段

// [作用]:判断Any字段addr是否被设置
bool has_addr() const;


// [作用]:清除对Any字段的设置(重置为默认值)
void clear_addr();


// [作用]:返回Any字段的内容
const ::PROTOBUF_NAMESPACE_ID::Any& addr() const;


// [作用]:用于获取Any消息中的 addr 成员变量,并返回一个指向 addr 的指针,可以通过这个指针修改该Any对象中 addr
::PROTOBUF_NAMESPACE_ID::Any* mutable_addr();
// [注意]:在使用 mutable_addr() 方法获取指针之前,需要确定该 Any 字段中存储的值已经被正确地解析为具体的类型,否则直接使用 mutable_addr() 可能会导致程序崩溃或者其他不可预知的问题


 // [作用]:释放 Any 对象中包含的数据(Any字段里的内容被重置为默认值),并返回一个指向释放数据的指针。也就是将该对象的所有权转移给调用方
 PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Any* release_addr();
// [注意]:该方法所释放的是 Any 类型对象中存储的对象的所有权,而非 Any 类型对象本身的所有权。

③ 类型转换

 前面提到,Any字段中可以存储任意消息类型,这就要涉及到任意消息类型和Any类型的互转。这部分代码就在Google为我们写好的头文件 any.pb.h 中。

// 将任意消息类型转为Any类型
bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message)
    
// 将Any类型转为任意消息类型
bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const
    
// 判断 Any 字段存储的对象类型是否为 T
template<typename T> bool Is() const

四、Contact 2.2 改写

write.cc:
image-20230610214850754

read.cc:

image-20230609172755758

区分下面的写法:

image-20230609171944727

🎯[说明]:

  • 正确:addr返回的是const对象。const对象才能调用const修改的函数
  • 错误:mutable_addr的对象是可以修改

image-20230609171849058

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罅隙`

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值