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

本文介绍了Protobuf的map类型,用于创建关联映射字段。文中详细讲解了map的基本认识,包括key和value的类型限制,以及不能使用repeated修饰。此外,还展示了如何向PeopleInfo消息中添加map字段,并提供了编译后生成的访问map的相关函数。最后,通过代码示例展示了如何在write.cc和read.cc中对map进行读写操作。
摘要由CSDN通过智能技术生成

2.4 map 类型

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

一、 基本认识

protobuf语法也支持我们创建创建关联映射字段,即使用map类型去声明字段:

map<key_type, val_type> mapfiled = N;

有以下几点需要注意:

  • key_type 可以为 float/doublebytes 外的任意标量类型,否则在编译时就会出错。而 value_type 可以为任意类型
    image-20230612140825868

  • map类型不可以用 repeated 修饰

  • 向map中插入的数据是 unordered

二、map相关函数

我们向 PeopleInfo 中增加一个 map 类型的remark字段:

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;
    oneof other_contact{
        string qq = 5;
        string wechat = 6;
    }
    // ------------- 新增内容 -----------------
    map<string, string> remark = 7;
    // ---------------------------------------
}

message Contact{
    repeated PeopleInfo contact = 1;
}

 编译 .prtoo 文件后观察新生成的部分函数。相信现在大家根据函数的名字就可以推断处对应的函数功能了

// 返回map的大小
inline int PeopleInfo::remark_size() const {}

// 清空map的内容
inline void PeopleInfo::clear_remark() {}

// 获取Map容器对象
inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, std::string >&
PeopleInfo::remark() const {}

// 返回指向Map容器对象的可变指针
inline ::PROTOBUF_NAMESPACE_ID::Map< std::string, std::string >*
PeopleInfo::mutable_remark() {}

三、contact2.4的改写

write.cc改写部分

for(int i = 0;; i++){
    cout << "请输入备注" << i + 1 << "标题(只回车退出): ";
    string title;
    getline(cin, title);
    if(title.empty()) break;

    cout << "请输入备注" << i + 1 << "内容: ";
    string content;
    getline(cin, content);
    p->mutable_remark()->insert({title, content}); 
}

image-20230612143130566

read.cc改写部分

// 首先判断map中是否有内容
if(people.remark_size() != 0){
    cout << "备注信息: " << endl;
}

// 可以使用迭代器遍历map的内容
for(auto iter =  people.remark().cbegin(); 
    iter != people.remark().cend(); iter++){
    cout << iter->first << " : " << iter->second << endl;
}

image-20230612143214576

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

罅隙`

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

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

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

打赏作者

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

抵扣说明:

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

余额充值