2.4 map 类型
本系列文章将通过对通讯录项目的不断完善,带大家由浅入深的学习Protobuf的使用。这是Contacts的2.4版本,在这篇文章中将带大家学习Protobuf的 map 语法,并将其用到我们的项目中
一、 基本认识
protobuf语法也支持我们创建创建关联映射字段,即使用map类型去声明字段:
map<key_type, val_type> mapfiled = N;
有以下几点需要注意:
-
key_type 可以为 float/double 和 bytes 外的任意标量类型,否则在编译时就会出错。而 value_type 可以为任意类型
-
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});
}
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;
}