当前位置: 首页 > news >正文

《protobuf》基础语法2

文章目录

  • 枚举类型
  • ANY 类型
  • oneof 类型
  • map 类型
  • 改进通讯录实例

枚举类型

protobuf里有枚举类型,定义如下

enum PhoneType
{string home_addr = 0;string work_addr = 1;
}

message一样,可分为 嵌套定义,文件内定义,文件外定义。不过多演示

但是值得注意的点是

  1. 同级(同层)的枚举类型,各个枚举类型中的常量不能重名,否则编译会报错。如下:
enum A
{int32 a = 0;
}
enum B
{int32 a = 0;
}

A和B有相同的变量a,所以会报错

  1. 单个 .proto 文件下,最外层枚举类型和嵌套枚举类型,不算同级。如下:
enum A
{int32 a = 0;
}
message C
{enum B{int32 a = 0;}
}
  1. 多个 .proto 文件下,若一个文件引入了其他⽂件,且每个文件都未声明 package,每个 proto 文
    件中的枚举类型都在最外层,算同级。如下:
// 在 A.proto 文件里
import "B.proto"
enum A
{int32 a = 0;   // 报错,B.proto 里以及定义
}
-----------------------
// 在 B.proto 文件里
enum B
{int32 a = 0;
}
  1. 多个 .proto 文件下,若一个文件引入了其他文件,且每个文件都声明了 package,不算同级。如下
// 在 A.proto 文件里
import "B.proto"
package A;
enum A
{int32 a = 0;
}
-----------------------
// 在 B.proto 文件里
package B;
enum B
{int32 a = 0;
}

ANY 类型

介绍一下ANY类型,ANY类型表示任意类型

  • 头文件位置 /usr/local/protobuf/include/google/protobuf/
    在这里插入图片描述

如何将其引入 .proto 文件里

// 在/usr/local/protobuf/include
import "google/protobuf/any.proto";
// 使用
message Any{google.protobuf.Any data = 1;
}
  • 介绍常用函数:
// 已知信息如下
/ contacts.proto文件  //
syntax = "proto3"
package contacts;
import "google/protobuf/any.proto";  // 引入Any类型
message PeopleInfo
{// 可以用于任何类型的anygoogle.protobuf.Any data = 1;
}message Address
{string home_addr;
} test.cc文件 //
#include <iostream>
#include "contacts.pb.h"  // contacts.proto 编译后生成的头文件
using namespace std;int main()
{// 包装contact2::PeopleInfo people;contact2::Address addr;addr.set_home_addr("中国");google::protobuf::Any* any = people.mutable_data();  // 开辟一段any对象的空间any->PackFrom(addr);  // 将addr打包成Any类型// 转换contact2::Address addr2;if(people.has_data()){google::protobuf::Any any = people.data();  // 获取people里的Any类对象 if(any.Is<contact2::Address>()) // 判断any类型是否为 Address 类{any.UnpackTo(&addr2);  // 输出型参数,填充add2cout << addr2.home_addr() << endl;  // 打印}}return 0;
}

编译 .proto 文件,然后编译连接 test.cc 文件,执行结果如下:
在这里插入图片描述

执行大致流程
在这里插入图片描述
分类讲解一下常用函数:

  • 属于people对象的
    • Any* mutable_data(); ------- // 开辟一段 any 对象的空间
    • Any& data() const; ----------- // 获得 any 对象(即:people里的data)
    • bool has_data() const; ------- // 判断有无对 any 对象赋值
  • 属于 people 里 Any类型的data 对象的
    • bool PackFrom(const Message& message); -------- // 将任意类型转换成 Any 类
    • bool UnpackTo(Message* message) const; -------- // 将 any 对象里的值赋给相对应类型的对象
    • template< class T> bool Is() const; -------- // 判断是否为对应类型

oneof 类型

oneof 类型语法简单:

  • 定义如下
message PeopleInfo
{string name = 1;oneof gender{string male = 2;string female = 3;}
}

但是值得注意的点是

  • 可选字段中的字段编号,不能与非可选字段的编号冲突。
  • 不能在 oneof 中使用 repeated 字段。
  • 将来在设置 oneof 字段中值时,如果将 oneof 中的字段设置多个,那么只会保留最后⼀次设置的成员,之前设置的 oneof 成员会自动清除。

看看编译后的 .pb.h 文件里定义的内容

class PeopleInfo final :public ::PROTOBUF_NAMESPACE_ID::Message 
{enum GenderCase {kMale = 2,kFemale = 3,GENDER_NOT_SET = 0,};// string male = 2;bool has_male() const;void clear_male();const std::string& male() const;template <typename ArgT0 = const std::string&, typename... ArgT>void set_male(ArgT0&& arg0, ArgT... args);std::string* mutable_male();PROTOBUF_NODISCARD std::string* release_male();void set_allocated_male(std::string* male);// string female = 3;bool has_female() const;void clear_female();const std::string& female() const;template <typename ArgT0 = const std::string&, typename... ArgT>void set_female(ArgT0&& arg0, ArgT... args);std::string* mutable_female();PROTOBUF_NODISCARD std::string* release_female();void set_allocated_female(std::string* female);void clear_gender();GenderCase gender_case() const;
}

会将 oneof 中的多个字段定义为⼀个枚举类型。

  • 设置和获取:对 oneof 内的字段进⾏常规的设置和获取即可,但要注意只能设置⼀个。如果设置多个,那么只会保留最后⼀次设置的成员
  • 清空oneof字段:clear_ 方法
  • 获取当前设置了哪个字段:_case 方法
  • 设置值方法: set_
  • 判断该值是否存在方法:has_

map 类型

类似于C++里面的 map 类型,protobuf自己实现了一个类似的数据结构,protobuf 的 map 类型的实现是基于它的 Message 类型的。

  • 定义如下
message PeopleInfo
{map<string, string> info = 1;
}

但是值得注意的点是

repeated map< key_type, value_type> map_name = N;

  • key_type 是除了 float 和 byte 的其他任何标量类型。value_type 可以是任意类型
  • map 也不可以被 repeated 修饰
  • map 中存入的元素是无序

讲解一下几个相关常用函数

  • 在PeopleInfo对象里,一般用 mutable_info ( 这里的 info 是对应map类对象 info ) 来开辟一段空间,返回 map 指针来操控info。
    函数原型Map< std::string, std::string >*mutable_info()
  • void clear_info(); 清空对象里的内容。

此外,map还支持迭代器,和C++里的 unorderedmap 十分类似。

改进通讯录实例

运用上述知识点,对上一篇的通讯录代码进行增添功能

contacts.proto

syntax = "proto3";
package contact2;// 在/usr/local/protobuf/include
import "google/protobuf/any.proto";// 地址信息
message Address
{string home_addr = 1;string work_addr = 2;
}
// 个人信息
message PeopleInfo
{string name = 1;int32 age = 2;// 嵌套定义message Phone{string number = 1;// 嵌套枚举enum PhoneType{MP = 0;  // 移动电话TEL = 1; // 固定电话}PhoneType type = 2;}// repeated 修饰词 修饰的变量相当于数组repeated Phone phone = 3;google.protobuf.Any data = 4;// 其他联系方式oneof other_contacts{string QQ = 5;string Wechat = 6;}// 备注map<string, string> remark = 7;
}// 通讯录
message Contacts
{repeated PeopleInfo contacts = 1;
}

write.cpp
在这里插入图片描述

执行结果

在这里插入图片描述

read.cpp

在这里插入图片描述
在这里插入图片描述

相关文章:

《protobuf》基础语法2

文章目录 枚举类型ANY 类型oneof 类型map 类型改进通讯录实例 枚举类型 protobuf里有枚举类型&#xff0c;定义如下 enum PhoneType {string home_addr 0;string work_addr 1; }同message一样&#xff0c;可分为 嵌套定义&#xff0c;文件内定义&#xff0c;文件外定义。不…...

利用 SOAR 加快事件响应并加强网络安全

随着攻击面的扩大和攻击变得越来越复杂&#xff0c;与网络攻击者的斗争重担落在了安全运营中心 &#xff08;SOC&#xff09; 身上。SOC 可以通过利用安全编排、自动化和响应 &#xff08;SOAR&#xff09; 平台来加强组织的安全态势。这一系列兼容的以安全为中心的软件可加快事…...

uni-app:通过ECharts实现数据可视化-如何引入项目

效果 引入文件位置 代码 <template><view id"myChart"></view> </template> <script> import echarts from /static/js/echarts.js // 引入文件 export default {mounted() {// 初始化EChartsconst myChart echarts.init(document…...

string 模拟与用法

string 用法 string string 模拟 #pragma once #include <assert.h> #include <string.h> #include <iostream>namespace sjy {class string{public://迭代器相关typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _st…...

[NLP] LLM---<训练中文LLama2(一)>训练一个中文LLama2的步骤

一 数据集 【Awesome-Chinese-LLM中文数据集】 【awesome-instruction-dataset】【awesome-instruction-datasets】【LLaMA-Efficient-Tuning-数据集】Wiki中文百科&#xff08;25w词条&#xff09;wikipedia-cn-20230720-filteredBaiduBaiKe&#xff08;563w词条&#xff09; …...

华为云云耀云服务器L实例使用教学 | 利用华为云服务器搭建--> 基于Spring Boot+WebSocket+WebRtc实现的多人自习室

文章目录 1. 购买华为云服务器L2. 在华为云服务器上搭建项目前期准备工作1. 更换登录密码2. 安全组配置 3. 在服务器上运行自己的项目 1. 购买华为云服务器L 在有优惠券的情况下&#xff0c;来到华为云这个网址下面&#xff0c;链接为&#xff1a;https://www.huaweicloud.com…...

Postman应用——接口请求(Get和Post请求)

文章目录 新增请求接口请求Get接口请求Post 这里只讲用的比较多的Get和Post请求方式&#xff0c;也可以遵循restful api接口规范&#xff0c;使用其他请求方式。 GET&#xff08;SELECT&#xff09;&#xff1a;从服务器取出资源&#xff08;一项或多项&#xff09;POST&#…...

k8s pod概念、分类及策略

目录 一.pod相关概念 &#xff12;.Kubrenetes集群中Pod两种使用方式 &#xff13;.pause容器的Pod中的所有容器共享的资源 &#xff14;.kubernetes中的pause容器主要为每个容器提供功能&#xff1a; &#xff16;.Pod分为两类&#xff1a; 二.Pod容器的分类 1.基础容器…...

C++系列-左移运算符重载

左移运算符重载 左移运算符的应用左移运算符的重载 左移运算符的应用 左移运算符&#xff0c;左移第一个操作数的位&#xff0c;第二个操作数决定要移动的位置左移运算符还可以用于输出调试&#xff0c;cout << “Hello” << endl; 左移运算符的重载 左移运算符…...

【Vue】vue中v-if的用法

v-if是Vue.js中常用的条件渲染指令&#xff0c;根据表达式的值来动态控制元素的显示或隐藏。具体的使用方法如下&#xff1a; 1.基本语法 <div v-if"condition"><!-- content --> </div>其中&#xff0c;v-if后面跟着一个表达式condition&#x…...

企业架构LNMP学习笔记54

企业架构NoSQL数据库之MongoDB。 学习目标和内容&#xff1a; 1&#xff09;能够简单描述mongoDB的使用特点&#xff1a; 2&#xff09;能够安装配置启动MongoDB&#xff1b; 3&#xff09;能够使用命令行客户端简单操作MongoDB&#xff1b; 4&#xff09;能够实现基本的数…...

C【函数】

1.常用API 1.strcpy&#xff1a;#include<string.h> char * strcpy ( char * destination, const char * source );int main(){char arr1[] "bit";char arr2[20] "###########";// bit\0########strcpy(arr2, arr1);printf("…...

【简单教程】利用Net2FTP构建免费个人网盘,实现便捷的文件管理

文章目录 1.前言2. Net2FTP网站搭建2.1. Net2FTP下载和安装2.2. Net2FTP网页测试 3. cpolar内网穿透3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 文件传输可以说是互联网最主要的应用之一&#xff0c;特别是智能设备的大面积使用&#xff0c;无论是个人…...

05-Flask-Flask查询路由方式

Flask查询路由方式 前言命令行方式代码实现返回所有路由 前言 本篇来学习下Flask中查询路由的方式 命令行方式 # window 用set linux 用 export set FLASK_APPtest_6_flask运行发方式# 打印所有路由 flask routes代码实现返回所有路由 # -*- coding: utf-8 -*- # Time …...

lua环境搭建数据类型

lua作为一门计算机语言&#xff0c;从语法角度个人感觉还是挺简洁的接下来我们从0开始学习lua语言。 1.首先我们需要下载lua开发工具包 在这里我们使用的工具是luadist 下载链接为&#xff1a;https://luadist.org/repository/下载后的压缩包解压后就能用。 2.接下来就是老生…...

c++11的一些新特性

c11 1. {}初始化2. 范围for循环3. final与override4. 右值引用4.1 左值引用和右值引用4.2 左值引用与右值引用比较 5. lambda表达式6. 声明6.1 auto6.2 decltype6.3 nullptr 7. 可变参数模版 1. {}初始化 在C中&#xff0c;使用花括号初始化的方式被称为列表初始化。列表初始化…...

K8S名称空间和资源配额

Kubernetes 支持多个虚拟集群&#xff0c;底层依赖于同一个物理集群。 这些虚拟集群被称为名称空间。名称空间namespace是k8s集群级别的资源&#xff0c;可以给不同的用户、租户、环境或项目创建对应的名称空间&#xff0c;例如&#xff0c;可以为test、dev、prod环境分别创建各…...

鼠标拖拽拖动盒子时,与盒子内某些点击事件冲突问题解决

目录 问题解决思路解决代码&#xff08;标注【主要代码】的为重点&#xff09; 问题 拖动该悬浮球时&#xff0c;鼠标弹起可能会触发悬浮球内事件 解决思路 鼠标拖动盒子时&#xff0c;将 isMove 设为 true 意为正在拖动盒子&#xff0c;此时将 class"btns_move" 遮…...

PMP项目管理证书是什么?有什么用?

什么是PMP证书&#xff1f; PMP全称是Project Management Professional&#xff0c;中文全称叫项目管理专业人士资格认证&#xff0c;是由美国项目管理协会(PMI)发起&#xff0c;严格评估项目管理人员知识技能是否具有高品质的资格认证考试&#xff0c;目的是为了给项目管理人…...

iframe的父子通讯

最近有个需求是在父页面打开一个弹窗&#xff0c;然后弹窗里面是一个iframe&#xff0c;在关闭弹窗时需要把iframe中的audio标签的音频链接清空和做一些其他的操作。因为以前很少接触iframe&#xff0c;所以对它有点陌生&#xff0c;在经过大佬的指点和上网查阅后找到了解决方法…...

使用docker创建minio镜像并上传文件,提供demo

使用docker创建minio镜像并上传文件&#xff0c;提供demo 1. 整体描述2. 环境搭建2.1 windows环境搭建2.2 docker部署 3. spring集成3.1 添加依赖3.2 配置文件3.3 创建config类3.4 创建minio操作类3.5 创建启动类3.6 测试controller 4. 测试操作4.1 demo运行4.2 页面查看4.3 上…...

02 java ---- Android 基础app开发

目录 相对布局 显示一个美女 显示两个美女 安卓APP启动过程 安卓布局控件 常用布局之相对布局 常用布局之相对布局 padding和margin 按键美化 常用布局之线性布局 安卓按键响应的几种方式 直接设置按键的onClick绑定的函数 自定义类实现按键监听事件的接口 匿名内…...

鲁棒性与稳定性区别

鲁棒性 所谓“鲁棒性”&#xff0c;是指控制系统在一定&#xff08;结构&#xff0c;大小&#xff09;的参数摄动下&#xff0c;维持其它某些性能的特性粗携。 稳定性 所谓“稳定性”&#xff0c;是指控制系统在使它偏离平衡状态的扰动作用消失后&#xff0c;返回原来平衡状…...

C++项目实战——基于多设计模式下的同步异步日志系统-⑦-日志输出格式化类设计

文章目录 专栏导读日志格式化类成员介绍patternitems 格式化子项类的设计抽象格式化子项基类日志主体消息子项日志等级子项时间子项localtime_r介绍strftime介绍 源码文件名子项源码文件行号子项线程ID子项日志器名称子项制表符子项换行符子项原始字符串子项 日志格式化类的设计…...

Android---底部弹窗之BottomSheetDialog

BottomSheetDialog 是Android开发中的一个弹出式对话框&#xff0c;它从屏幕底部弹出并覆盖部分主界面。 1. BottomSheetDialog的使用 // 参数2&#xff1a;设置BottomSheetDialog的主题样式&#xff1b;将背景设置为transparent&#xff0c;这样我们写的shape_bottom_sheet_…...

Cesium 地球网格构造

Cesium 地球网格构造 Cesium原理篇&#xff1a;3最长的一帧之地形(2&#xff1a;高度图) HeightmapTessellator 用于从高程图像创建网格。提供了一个函数 computeVertices&#xff0c;可以根据高程图像创建顶点数组。 该函数的参数包括高程图像、高度数据的结构、网格宽高、…...

C++深度优化——cacheline测试

cacheline是内存调度的基本结构&#xff0c;其大小一般为32B或者64B。关于本机具体的配置信息可以在配置文件中看到&#xff1a; 这里可以看到我的这台机器的cacheline大小是64B。对于cacheline在多核处理器中有一个伪共享的状态&#xff0c;具体可以参考以下博客&#xff1a;高…...

【数字IC/FPGA】Verilog中的递归调用

参考文章 在Verilog2001中,模块的递归调用是可能的,引用下面的一段话(出自上面的参考文章) Many designers think that recursive techniques cannot be applied to hardware design. I’m not really sure where this misconception comes from. While it is true that i…...

禁用Win10自动更新

第一步&#xff0c;winr&#xff0c;输入 gpedit.msc 并回车&#xff0c;打开【组策略】 第二步&#xff0c;依次点击 管理模板->Windows组件->Windows更新 第三步&#xff0c;双击Windows更新&#xff0c;然后在设置中双击 指定 intranet Microsoft 更新服务位置 第…...

算法通关村-----动态规划高频问题

最少硬币数问题 问题描述 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。你可以认为每种硬…...

渭南网站建设wifi/哈尔滨网站推广

多进程应用大批量的数据是非常舒服的一件事情。 处理之前理解两个概念&#xff1a;孤儿进程和僵尸进程 孤儿进程&#xff1a; 是指父进程在fork出子进程后&#xff0c;自己先完了。这个问题很尴尬&#xff0c;因为子进程从此变得无依无靠、无家可归&#xff0c;变成了孤儿。用术…...

那个网站可以看高速的建设情况/百度收录是什么意思

Docker环境下DB2的安装与图形化管理 docker是一个一款很轻便的应用容器引擎&#xff0c;为了更好的管理和使用docker&#xff0c;使用web可视化管理工具似乎更符合大多数人的需求。在这里&#xff0c;给大家分享下自己使用过的几款web工具&#xff1a;docker UI、shipyard、po…...

北京交易中心网站/什么是友情链接?

二叉树的镜像(十八) 题目描述 操作给定的二叉树&#xff0c;将其变换为源二叉树的镜像。 输入描述: 二叉树的镜像定义&#xff1a; 源二叉树 8/ \6 10/ \ / \5 7 9 11镜像二叉树8/ \10 6/ \ / \11 9 7 5代码(已在牛客上 AC) class Solution { public:void Mirror(…...

思茅网站建设/数字营销成功案例

1:知识点1:在定义一个类时,我们可以显式或隐式的定义在此类型的对象拷贝、赋值、移动、销毁是做什么,主要通过五种特殊的成员函数来完成这些操作:拷贝构造函数、拷贝复制运算符、移动构造函数、移动复制运算符。析构函数 知识点2:拷贝和移动构造函数定义了当用同类型的一…...

为推广网站做的宣传活动/搜索引擎优化seo应用

浮动的特点 1.脱离文档流 2.浮动元素会脱离文档流并向左/向右浮动&#xff0c;直到碰到父元素或另一个浮动元素 3.会导致父元素高度坍塌 早期为实现文字环绕效果 清除浮动 一个常用的clearfix清除浮动方法&#xff1a; .clearfix:before,//befor以解决现代浏览器上边距折叠的问…...

什么是物联网/武汉关键词seo

计算机组装与维护期中试卷一、填空(每空1分&#xff0c;共20分)1.计算机系统由_软件系统_与___硬件系统_两大部分组成。2.安装CPU时涂抹硅脂的目的是为了更好地对CPU进行散热。3.最常见的主板BIOS主要有三大类型&#xff0c;即Award、AMI和 Phoenix三种。4.鼠标按其工作原理的不…...