[C++][ProtoBuf][Proto3语法][二]详细讲解

目录

  • 1.Any类型
    • 1.说明
    • 2.代码&使用
  • 2.oneof类型
    • 1.说明
    • 2.代码&使用
  • 3.map类型
    • 1.说明
    • 2.代码&使用


1.Any类型

1.说明

  • 字段还可以声明为Any类型,可以理解为泛型类型
    • 使⽤时可以在Any存储任意消息类型
      • 父类是Message
    • Any类型的字段也可以⽤repeated来修饰
  • Any类型是Google已经定义好的类型,其中的include⽬录下查找所有Google已经定义好的.proto⽂件
    • 以我的机器为例ls /usr/include/google/protobuf

2.代码&使用

  • .proto文件
    syntax = "proto3";
    package contacts;import "google/protobuf/any.proto"; // 引⼊ any.proto ⽂件message Address
    {string home_address = 1;string unit_address = 2;
    }message PeopleInfo 
    {string name = 1;int32 age = 2;message Phone {string number = 1;enum PhoneType {MP = 0;TEL = 1;}PhoneType type = 2;}repeated Phone phone = 3;google.protobuf.Any data = 4;
    }message Contacts 
    {repeated PeopleInfo contacts = 1;
    }
    
  • 编译生成的CPP代码
    // 新⽣成的 Address 类
    class Address final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {
    public:using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;void CopyFrom(const Address& from);using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;void MergeFrom( const Address& from) {Address::MergeImpl(*this, from);}// string home_address = 1;void clear_home_address();const std::string& home_address() const;template <typename ArgT0 = const std::string&, typename... ArgT>void set_home_address(ArgT0&& arg0, ArgT... args);std::string* mutable_home_address();PROTOBUF_NODISCARD std::string* release_home_address();void set_allocated_home_address(std::string* home_address);// string unit_address = 2;void clear_unit_address();const std::string& unit_address() const;template <typename ArgT0 = const std::string&, typename... ArgT>void set_unit_address(ArgT0&& arg0, ArgT... args);std::string* mutable_unit_address();PROTOBUF_NODISCARD std::string* release_unit_address();void set_allocated_unit_address(std::string* unit_address);
    };// 更新的 PeopleInfo 类
    class PeopleInfo final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {
    public:// .google.protobuf.Any data = 4;bool has_data() const;void clear_data();const ::PROTOBUF_NAMESPACE_ID::Any& data() const;PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Any* release_data();::PROTOBUF_NAMESPACE_ID::Any* mutable_data();void set_allocated_data(::PROTOBUF_NAMESPACE_ID::Any* data);
    };
    
  • 上述代码中,对于Any字段
    • 设置和获取
      • 获取⽅法的⽅法名称与字段命名完全相同
      • 设置⽅法可以使⽤mutable_⽅法,返回值为Any类型的指针,这类⽅法会为用户开辟好空间,可以直接对这块空间的内容进⾏修改
    • 可以在Any字段中存储任意消息类型,这就要涉及到任意消息类型和Any类型的互转
      • PackFrom():将任意消息类型转为Any类型
      • UnpackTo:将Any类型转回之前设置的任意消息类型
      • Is:用来判断存放的消息类型是否为typename T
      • 这部分代码就在 Google写好的⽂件any.pb.h
        class PROTOBUF_EXPORT Any final : public ::PROTOBUF_NAMESPACE_ID::Message 
        {bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) {...}bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const {...}template<typename T> bool Is() const {return _impl_._any_metadata_.Is<T>();}
        };
        

2.oneof类型

1.说明

  • 如果消息中有很多可选字段, 并且将来同时只有⼀个字段会被设置
    • 那么就可以使⽤oneof加强这个⾏为,也能有节约内存的效果
  • 注意
    • 可选字段中的字段编号,不能与⾮可选字段的编号冲突
    • 不能在oneof中使⽤repeated字段
    • 将来在设置oneof字段中值时,如果将oneof中的字段设置多个,那么只会保留最后⼀次设置的成员,之前设置的oneof成员会⾃动清除

2.代码&使用

  • .proto文件
    syntax = "proto3";
    package contacts;import "google/protobuf/any.proto"; // 引⼊ any.proto ⽂件message Address
    {string home_address = 1;string unit_address = 2;
    }message PeopleInfo 
    {string name = 1;int32 age = 2;message Phone {string number = 1;enum PhoneType {MP = 0;TEL = 1;}PhoneType type = 2;}repeated Phone phone = 3;google.protobuf.Any data = 4;// 其他联系⽅式:多选⼀oneof other_contact { string qq = 5; string weixin = 6;}
    }message Contacts 
    {repeated PeopleInfo contacts = 1;
    }
    
  • 编译生成的CPP代码
    // 更新的 PeopleInfo 类
    class PeopleInfo final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {enum OtherContactCase {kQq = 5,kWeixin = 6,OTHER_CONTACT_NOT_SET = 0,};// string qq = 5;bool has_qq() const;void clear_qq();const std::string& qq() const;template <typename ArgT0 = const std::string&, typename... ArgT>void set_qq(ArgT0&& arg0, ArgT... args);std::string* mutable_qq();PROTOBUF_NODISCARD std::string* release_qq();void set_allocated_qq(std::string* qq);// string weixin = 6;bool has_weixin() const;void clear_weixin();const std::string& weixin() const;template <typename ArgT0 = const std::string&, typename... ArgT>void set_weixin(ArgT0&& arg0, ArgT... args);std::string* mutable_weixin();PROTOBUF_NODISCARD std::string* release_weixin();void set_allocated_weixin(std::string* weixin);void clear_other_contact();OtherContactCase other_contact_case() const;
    };
    
  • 上述的代码中,对于oneof字段
    • 会将oneof中的多个字段定义为一个枚举类型
    • 设置和获取
      • oneof内的字段进⾏常规的设置和获取即可
      • 但要注意只能设置⼀个,如果设置 多个,那么只会保留最后⼀次设置的成员
    • 清空oneof字段:clear_⽅法
    • 获取当前设置了哪个字段:_case⽅法

3.map类型

1.说明

  • 语法⽀持创建⼀个关联映射字段,也就是可以使⽤map类型去声明字段类型,格式
    map<key_type, value_type> map_field = N;
    
  • 注意
    • key_type是除了floatbytes类型以外的任意标量类型
    • value_type可以是任意类型
    • map字段不可以repeated修饰
    • map 中存⼊的元素是⽆序的

2.代码&使用

  • .proto文件
    syntax = "proto3";
    package contacts;import "google/protobuf/any.proto"; // 引⼊ any.proto ⽂件message Address
    {string home_address = 1;string unit_address = 2;
    }message PeopleInfo 
    {string name = 1;int32 age = 2;message Phone {string number = 1;enum PhoneType {MP = 0;TEL = 1;}PhoneType type = 2;}repeated Phone phone = 3;google.protobuf.Any data = 4;// 其他联系⽅式:多选⼀oneof other_contact {string qq = 5; string weixin = 6;}map<string, string> remark = 7;
    }message Contacts 
    {repeated PeopleInfo contacts = 1;
    }
    
  • 编译生成的CPP文件
    // 更新的 PeopleInfo 类
    class PeopleInfo final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {// map<string, string> remark = 7;int remark_size() const;void clear_remark();const ::PROTOBUF_NAMESPACE_ID::Map< std::string, std::string >& remark() const;::PROTOBUF_NAMESPACE_ID::Map< std::string, std::string >* mutable_remark();
    };
    
  • 上述的代码中,对于Map类型的字段
    • 清空map:clear_ ⽅法
    • 设置和获取
      • 获取⽅法的⽅法名称与字段命名完全相同
      • 设置⽅法mutable_⽅法,返回值为Map类型的指针,这类⽅法会为用户开辟好空间,可以直接对这块空间的0内容进⾏修改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/43217.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始搭建vite开发环境

准备 nodejs 18 pnpm https://vitejs.cn/ 开始 pnpm init pnpm add -D vite新建index.html <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width…

飞睿智能无线高速uwb安全数据传输模块,低功耗、抗干扰超宽带uwb芯片传输速度技术新突破

在信息化的时代&#xff0c;数据传输的速度和安全性无疑是每个企业和个人都极为关注的话题。随着科技的飞速发展&#xff0c;超宽带&#xff08;Ultra-Wideband&#xff0c;简称UWB&#xff09;技术凭借其性能和广泛的应用前景&#xff0c;逐渐成为了数据传输领域的新星。今天&…

JavaScript学习笔记(七)

45.9 JavaScript 可迭代对象 可迭代对象&#xff08;Iterables&#xff09;是可以使用 for..of 进行迭代的对象。 从技术上讲&#xff0c;可迭代对象必须实现 Symbol.iterator 方法。 45.9.1 遍历字符串 <body><p id"demo"></p><script>c…

使用vllm部署大语言模型

vLLM是一个快速且易于使用的库&#xff0c;用于LLM&#xff08;大型语言模型&#xff09;推理和服务。通过PagedAttention技术&#xff0c;vLLM可以有效地管理注意力键和值内存&#xff0c;降低内存占用和提高计算效率。vLLM能够将多个传入的请求进行连续批处理&#xff0c;从而…

PTrade常见问题系列5

回测失败&#xff1a;可用资源不足。 回测运行失败&#xff0c;错误码&#xff1a;2 错误信息&#xff1a;可用资源不足&#xff0c;请稍后在创建。 1、之前客户未限制客户容器使用内存和CPU&#xff0c;周末修改配置&#xff0c;限制了内存和CPU&#xff1b; 2、此报错是用户…

【Javascript】微信小程序项目结构目录详解

我白天是个 搞笑废物 表演不在乎 夜晚变成 忧伤怪物 撕扯着孤独 我曾经是个 感性动物 小心地感触 现在变成 无关人物 &#x1f3b5; 张碧晨/王赫野《何物》 微信小程序开发工具提供了一个便捷的开发环境&#xff0c;使开发者可以快速构建和部署小程序。在…

代码随想录算法训练营Day38|1049. 最后一块石头的重量 II , 494. 目标和 , 474.一和零

好久不见&#xff0c;兄弟们&#xff0c;我终于把期末考试考完了&#xff0c;现在已经放暑假回家了&#xff0c;开始恶补算法了&#xff0c;那么废话不多说&#xff0c;来看今天的内容 1049. 最后一块石头的重量 II&#xff1a;代码随想录 这道题目的意思就是给你一个数组表示每…

【Python】已解决:FileNotFoundError: [Errno 2] No such file or directory: ‘D:\1. PDF’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;FileNotFoundError: [Errno 2] No such file or directory: ‘D:\1. PDF’ 一、分析问题背景 在Python编程中&#xff0c;当你尝试打开一个不存在的文件时&…

索引唯一约束问题SQL

新增报错违反唯一约束条件 (JING_DIAN.SYS_C0096533) 【问题原因】 这个问题可能是由于在Oracle APEX中&#xff0c;虽然你创建了一个名为"ISEQ_520227"的索引&#xff0c;但是在插入数据时&#xff0c;违反了唯一约束条件。这可能是因为你的数据表中已经存在相同的…

压测引擎数据库设计(上)

压测引擎数据库设计&#xff08;上&#xff09; 引言 在当今快速发展的互联网时代&#xff0c;软件质量保证和性能测试变得尤为重要。自动化测试平台&#xff0c;提供了一套完整的解决方案&#xff0c;以确保软件产品在发布前能够满足性能和稳定性的要求。本文将深入探讨滴云自…

jmeter-beanshell学习6-beanshell生成测试报告

前面写了各种准备工作&#xff0c;内容组合用起来&#xff0c;应该能做自动化了&#xff0c;最后一步&#xff0c;生成一个报告&#xff0c;报告格式还是csv 报告生成的路径和文件&#xff0c;在用户参数写好&#xff0c;防止以后改路径或者名字&#xff0c;要去代码里面改。以…

[AHK V2]AHK能取消正常窗口的双击标题栏最大化事件吗?

问题&#xff1a; AHK能取消正常窗口的双击标题栏最大化事件吗&#xff1f; 解答&#xff1a; AutoHotkey (AHK)是一个强大的脚本语言&#xff0c;可以用来自定义键盘快捷键、鼠标操作等。如果你想阻止双击Windows标题栏进行最大化操作&#xff0c;你可以编写一个脚本来拦截…

Django自动生成Swagger接口文档 —— Python

1. 前言 当接口开发完成&#xff0c;紧接着需要编写接口文档。传统的接口文档通常都是使用Word或者一些接口文档管理平台进行编写&#xff0c;但此类接口文档维护更新比较麻烦&#xff0c;每次接口有变更&#xff0c;需要手动修改接口文档。在实际的工作中&#xff0c;经常会遇…

tomcat的优化和tomcat和nginx实现动静分离:

tomcat的优化 tomcat自身的优化 tomcat的并发处理能力不强。大项目不使用tomcat做为转发动态的中间件&#xff08;k8s集群&#xff0c;python&#xff0c;rubby&#xff09;&#xff0c;小项目会使用&#xff08;内部使用&#xff09;&#xff0c;动静分离。 优化tomcat的启动…

Python入门 2024/7/8

目录 数据容器 dict(字典&#xff0c;映射) 语法 定义字典字面量 定义字典变量 定义空字典 从字典中基于key获取value 字典的嵌套 字典的常用操作 新增元素 更新元素 删除元素 清空字典 获取全部的key 遍历字典 统计字典内的元素数量 练习 数据容器的通用操作…

linux环境下echo命令简单测试端口是否连通——筑梦之路

语法格式 echo > /dev/tcp/目标主机地址/端口号 示例 echo > /dev/tcp/example.com/80 当命令执行后&#xff0c;若端口是开放的&#xff0c;命令不会有任何输出并且会立即返回命令提示符&#xff1b;若端口未开放或连接失败&#xff0c;则可能由于网络问题、防火墙限…

在公司的业务杂记1之多选部门且主表没有部门字段(子表查询)

原型 1.新建&#xff0c;上传报告可多选部门 2.查询&#xff0c;可多选部门 数据库&#xff08;Postgresql&#xff09; 方式一 新增字段Jsonb&#xff1a; CREATE TABLE public.admin_report (admin_report_uuid uuid DEFAULT gen_random_uuid() NOT NULL,admin_report_tit…

java —— JSP 技术

一、JSP &#xff08;一&#xff09;前言 1、.jsp 与 .html 一样属于前端内容&#xff0c;创建在 WebContent 之下&#xff1b; 2、嵌套的 java 语句放置在<% %>里面&#xff1b; 3、嵌套 java 语句的三种语法&#xff1a; ① 脚本&#xff1a;<% java 代码 %>…

安全防御第三天(笔记持续更新)

1.接口类型以及作用 接口 --- 物理接口 三层口 --- 可以配置IP地址的接口 二层口 普通二层口 接口对 --- “透明网线” --- 可以将一个或者两个接口配置成为接口对&#xff0c;则 数据从一个接口进&#xff0c;将不需要查看MAC地址表&#xff0c;直接从另一个接口出&#xff1b…

机器学习模型运用在机器人上

机器学习模型在机器人技术中的应用非常广泛&#xff0c;涵盖了从简单的运动控制到复杂的认知和交互功能。以下是几种机器学习模型在机器人上的典型应用&#xff1a; 感知与识别&#xff1a; 计算机视觉&#xff1a;使用卷积神经网络&#xff08;CNNs&#xff09;识别和理解视觉…