[Protobuf]常见数据类型以及使用注意事项
[Protobuf]常见数据类型以及使用注意事项
@水墨不写bug
文章目录
- 一、基本数据类型
- 1、字段
- 2、字段的修饰规则
- 二、自定义数据类型
- 1、message类型
- 2、enum类型
- 3、Any类型
- 4、oneof类型
- 5、map类型
- 三、小工具
- 1.hexdump
- 2.decode
- 四、注意事项
一、基本数据类型
protobuf 支持多种基础数据类型,常用的有:
类型 | 说明 | 可选值范围(部分) |
---|---|---|
double | 64位浮点数 | ±1.7E±308 |
float | 32位浮点数 | ±3.4E±38 |
int32 | 使用变长编码[1]。负数的编码效率较低⸺若字段可能为负值,应使用 sint32 代替 | -2^31 到 2^31-1 |
int64 | 使用变长编码[1]。负数的编码效率较低⸺若字段可能为负值,应使用 sint64 代替 | -2^63 到 2^63-1 |
uint32 | 无符号32位整型 ,使用变长编码[1] | 0 到 2^32-1 |
uint64 | 无符号64位整型 ,使用变长编码[1] | 0 到 2^64-1 |
sint32 | 有符号32位整型(高效编码负数) | -2^31 到 2^31-1 |
sint64 | 有符号64位整型(高效编码负数) | -2^63 到 2^63-1 |
fixed32 | 定长 4 字节。若值常大于2^28 则会比 uint32 更高效。 | 0 到 2^32-1 |
fixed64 | 定长 8 字节。若值常大于2^56 则会比 uint64 更高效。 | 0 到 2^64-1 |
sfixed32 | 固定32位有符号整型(固定长度编码) | -2^31 到 2^31-1 |
sfixed64 | 固定64位有符号整型(固定长度编码) | -2^63 到 2^63-1 |
bool | 布尔值 | true/false |
string | 包含 UTF-8 和 ASCII 编码的字符串,长度不能超过 2^32 | 任意长度字符串 |
bytes | 可包含任意的字节序列但长度不能超过 2^32 | 任意长度字节数组 |
注:[1] 变长编码是指:经过protobuf 编码后,原本4字节或8字节的数可能会被变为其他字节数
1、字段
在定义一个字段之后,会给字段设置一个唯一标记值。同一个消息体内,字段标记值不能重复。
message PersonInfo
{int id = 1;string name = 1;//(字段标志重复)
}
消息体内的消息体可以重新计算标记值:
message PersonInfo
{int id = 1;string name = 2;message Phone{string number = 1;//(重新计算标记值)}
}
其次:
字段名称命名规范:全小写字母,多个字母之间用 _ 连接。
字段类型分为:基本数据类型 和 特殊类型(包括枚举enum、消息类型message等)。
字段唯⼀编号:用来标识字段,⼀旦开始使用就不能够再改变
字段编号的范围为:
1 ~ 536,870,911 (2^29 - 1) ,其中 19000 ~ 19999 不可用
范围为 1 ~ 15 的字段编号需要一个字节进行编码, 16 ~ 2047内的数字需要两个字节进行编码。编码后的字节不仅只包含了编号,还包含了字段类型。所以 1 ~ 15要用来标记出现非常频繁的字段,要为将来有可能添加的、频繁出现的字段预留一些出来。
2、字段的修饰规则
singular:消息中可以包含该字段零次或⼀次(不超过⼀次)。 proto3 语法中,字段默认使用该规则。
repeated:消息中可以包含该字段任意多次(包括零次),其中重复值的顺序会被保留。可以理解为定义了⼀个数组。
二、自定义数据类型
1、message类型
一个message类型被protoc编译器编译之后形成对应class。message可以嵌套message,同一层message,字段编号不能重复。message可作为类型来使用,对应class类型组合。
2、enum类型
定义enum类型的值,直接用名称+常量表示:
例如:
enum PhoneType //枚举名称的名称建议用驼峰命名
{MP = 0;TEL = 1;
}
常量值从0开始,只能为正值,不能为负。枚举类型也可定义在message体内部。
在同一层级内,不同的枚举类型内的同名常量值不能相同:
例如:
enum PhoneType
{MP = 0;TEL = 1;
}
enum PhoneTypeCopy
{MP = 0;
}
否则会报错重定义。
改为不重名即可:
enum PhoneType
{MP = 0;TEL = 1;
}
enum PhoneTypeCopy
{MP_C = 0;
}
类似的还有两个没有限制package的文件,import后也会出现上述类似问题。
解决方法是加上package限制。
3、Any类型
泛型类型,可以存放任意类型的数据。
是google直接写好的,使用前需要
import "google/protobuf/any.proto";
声明变量的格式如下:
message PeopleInfo
{google.protobuf.Any data = 0;
}
使用any类型需要常用的接口:
// .google.protobuf.Any data = 4;
bool has_data() const;//是否有数据
void clear_data();//清除数据
const ::PROTOBUF_NAMESPACE_ID::Any& data() const;//get
::PROTOBUF_NAMESPACE_ID::Any* mutable_data();//set
//把任意类型转化为any类型
bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message);
//重载类型
bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message,::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix);
//把any类型转化为任意类型
bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const;
//判断Any类型是否是T类型
template<typename T> bool Is() const {return _impl_._any_metadata_.Is<T>();}
4、oneof类型
被oneof声明的多个字段只能保留最后被设置的一个:
oneof other_contact
{string qq = 5;string wechat = 6;
}
qq和微信字段只会保留最后一次被设置的值。
oneof内部不能使用repeated修饰字段。
常用方法包括clear,set,get。不同的是多了一个has方法,用来表明是否有这个方法。
在对应生成的Cpp代码中,oneof类型定义的多个类型会被转化为一个enum类型。内部除了oneof内部的类型之外,还有一个NOT_SET = 0常量值。
5、map类型
类似于C++的map,定义protobuf的map需要注意,key_type只能是float,bytes类型之外的标量类型。val_type可以是任意类型。
map不能被repeated修饰。
设置的key-val键值对是无序的。
常用方法:size,clear,get,set。
三、小工具
1.hexdump
hexdump是Linux下的⼀个二进制文件查看工具,它可以将二进制文件转换为ASCII、八进制、十进制、十六进制格式进行查看。
-C: 表示每个字节显示为16进制和相应的ASCII字符
这个工具意义在于把protobuf序列化后的二进制转化为ASCII,便于查看。
2.decode
ProtoBuf 提供的一个命令选项 --decode ,表表示从标准输入中读取给定类型的二进制消息,并将其以文本格式写入标准输出。 消息类型必须在 .proto 文件或导入的文件中定义。
protoc --decode=contacts.Contacts contacts.proto < contacts.bin
这条命令用于解码一个用 Protocol Buffers(protobuf)序列化后的二进制文件 contacts.bin
,并将其内容以可读的文本格式输出。下面是这条命令的详细解释:
-
protoc
这是 Protocol Buffers 的编译器命令行工具,用于编译 .proto 文件和处理 protobuf 数据。 -
–decode=contacts.Contacts
这个参数的意思是用.proto
文件中定义的contacts.Contacts
这个消息类型来解码输入的数据。contacts
是 proto 文件中的包名(package)。Contacts
是 proto 文件中定义的消息类型(message)。
-
contacts.proto
这是 protobuf 的协议文件,里面定义了数据结构(消息类型、包名等)。protoc
会用它来知道怎么解析二进制数据。 -
< contacts.bin
这表示将contacts.bin
文件中的二进制数据(用 protobuf 序列化过的)作为标准输入传给protoc
。
四、注意事项
-
字段编号(tag)不可轻易变更
字段编号 是二进制格式的唯一标识,不能随意修改或复用,否则会导致兼容性问题。 -
尽量避免删除字段
如果需要废弃字段,可用reserved
关键字保留该 tag 和字段名。 -
字段类型不能随意更改
特别是从一种类型改为不兼容的另一种类型(如 int32 改为 string),会导致解析错误。 -
repeated 字段适合表达数组或列表
表示 0 个或多个同类型数据项。例如 repeated int32 scores。 -
嵌套 message 和 enum
可以在 message 内部定义子 message 或 enum,便于结构化复杂数据。 -
避免使用 float/double 存储精确金额
由于浮点数精度问题,金额等精确数据建议用 int64/uint64 表示最小单位(如分、厘)。 -
bytes 与 string 区别
string 专为 UTF-8 文本,bytes 则可存储任意二进制数据,如图片、加密内容等。
完~
未经作者同意禁止转载
相关文章:

[Protobuf]常见数据类型以及使用注意事项
[Protobuf]常见数据类型以及使用注意事项 水墨不写bug 文章目录 一、基本数据类型1、字段2、字段的修饰规则 二、自定义数据类型1、message类型2、enum类型3、Any类型4、oneof类型5、map类型 三、小工具1.hexdump2.decode 四、注意事项 一、基本数据类型 protobuf 支持多种基础…...
【C/C++】面试基础题目收集
C 软件开发面试中常见的刷题题目通常可分为以下几大类:数据结构与算法、系统编程、面向对象设计、C 语言特性、并发编程等。 🧠 一、数据结构与算法(力扣/牛客经典题) 掌握 STL 和底层结构实现能力: 📌 数…...

模拟实现线程池(线程数目为定值)和定时器
前言 昨天学习关于定时器的相关知识。今天花时间去模拟实现了一个定时器,同时也去模拟实现了一个线程池(线程数目为定值)。我感觉我收获了很多,对于线程的理解加深了。跟大家分享一下~ 线程池和定时器(这个是主要)的实现 代码 线程池 import java.ut…...

数据结构之队列实验
引言 在计算机科学中,进制转换是基础但重要的操作。例如将一个十进制数转换为二进制或八进制表示时,我们通常使用“短除法”——即不断用目标进制去除当前数,记录余数,直到商为0为止。 这种方法得到的是低位先产生的结果&#x…...
Java求职者面试题详解:计算机网络、操作系统、设计模式与数据结构
Java求职者面试题详解:计算机网络、操作系统、设计模式与数据结构 第一轮:基础概念问题 1. 请解释什么是HTTP协议? HTTP(HyperText Transfer Protocol)是一种用于传输超文本的协议,它定义了客户端和服务…...
每日八股文6.1
每日八股-6.1 Go1.Sync.map的底层实现2.结构体的tag如何获取?3.Go实现单例模式(使用sync.Once)4.Go实现单例模式(不使用sync.Once)5.make和new的区别6.Go项目引用包为什么用_以及包的init()函数7.如何判断一个结构体是…...

【Ubuntu】摸鱼技巧之虚拟机环境复制
前言 提示:所有的操作都需要关闭虚拟机 如何快速在其它电脑布置,linux环境,如果我们有一个环境直接拷贝就有时间摸鱼呀。 1.直接复制简单粗暴 不做赘述,如果不会复制,那么请右击鼠标压缩复制 2.克隆虚拟机 2.1 …...

室内VR全景助力房产营销及装修
在当今的地产行业,VR全景已成为不可或缺的应用工具。从地产直播到楼市VR地图,从效果图到水电家装施工记录,整个地产行业的上下游生态中,云VR全景的身影无处不在。本文将探讨VR全景在房产营销及装修领域的应用,并介绍众…...

jenkins集成gitlab实现自动构建
jenkins集成gitlab实现自动构建 前面我们已经部署了Jenkins和gitlab,本文介绍将二者结合使用 项目源码上传至gitee提供公网访问:https://gitee.com/ye-xiao-tian/my-webapp 1、创建一个群组和项目 2、添加ssh密钥 #生成密钥 [rootgitlab ~]# ssh-keyge…...
【C语言练习】070. 编写代码处理C语言中的异常情况
070. 编写代码处理C语言中的异常情况 070. 编写代码处理C语言中的异常情况C语言异常处理的基本思路返回值检查示例errno使用示例setjmp/longjmp示例最佳实践建议1. 使用返回值检查错误2. 使用全局变量记录错误状态3. 使用回调函数或信号处理程序4. 使用`setjmp`和`longjmp`示例…...
Java基本数据类型、抽象类和接口、枚举、时间类、String类全面介绍
JAVA基本数据类型知识总结 基本数据类型(Primitive Types) 类型占用字节默认值范围示例byte10-128 ~ 127byte a 100;short20-32,768 ~ 32,767short b 2000;int40-2 ~ 2-1int c 100000;long80L-2⁶ ~ 2⁶-1long d 10000000000L;float40.0f~7位小数f…...

Spring Boot微服务架构(八):开发之初就引入APM工具监控
使用 APM(Application Performance Management)工具监控 Spring Boot 应用,可以帮助开发者实时追踪性能瓶颈、分析调用链路、监控资源使用情况,并快速定位故障。以下是详细的步骤和常用工具的选择指南: 一、常用 A…...

大规模真实场景 WiFi 感知基准数据集
一段话总结 本文提出CSI-Bench,首个大规模真实场景WiFi感知基准数据集,覆盖26个室内环境、35名用户、16种商用设备,包含461小时有效数据,支持跌倒检测、呼吸监测、定位、运动源识别等单任务及用户身份、活动、 proximity联合标注的多任务学习。通过标准化评估协议和基线模…...

Python实现HPSO-TVAC优化算法优化支持向量机SVC分类模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在当今数据驱动的时代,支持向量机(SVM)作为一种经典的机器学习算法,…...

ck-editor5的研究 (3):初步使用 CKEditor5 的事件系统和API
前言 在上一篇文章中—— ck-editor5的研究(2):对 CKEditor5 进行设计,并封装成一个可用的 vue 组件 ,我已经把 CKEditor5 封装成了一个通用vue组件,并且成功在nuxt中运行,并具备一定的通用性&…...
使用ReactNative加载HarmonyOS Svga动画
这是一款使用ReactNative 加载HarmonyOS Svga动画的播放器插件 三端Svga动画统一使用点击这里 版本:v1.1.5 react-native-ohos-svgaplayer [!TIP] Github 地址 安装与使用 npm npm install react-native-ohos-svgaplayer yarn yarn add react-native-ohos-svgaplayer下面…...

WPS快速排版
论文包括(按顺序):封面(含题目)、摘 要、关键词、Abstract(英文摘要)、Keywords、目录、正文、参考文献、在读期间发表的学术论文及研究成果,致 谢 题目(黑小一加粗&…...

Java实现命令行图书管理系统(附完整源码)
一、项目概述 本文将介绍如何使用Java实现一个基于命令行的图书管理系统。系统支持管理员和普通用户两种角色,提供图书的增删改查、借阅归还等功能。项目采用面向对象设计原则,代码结构清晰,适合Java初学者学习。 二、系统功能架构 graph T…...
使用Docker-NVIDIA-GPU开发配置:解决 Docker NVIDIA 运行时错误方法
问题描述 运行 Docker 命令时,系统提示 docker: Error response from daemon: unknown or invalid runtime name: nvidia,表明 Docker 无法识别 NVIDIA 运行时。这一错误通常出现在使用 --runtime=nvidia 和 --gpus 参数时,意味着 NVIDIA 容器运行时未正确安装或配置。NVID…...
如何更好的理解云计算和云原生?
本文介绍什么是云计算、什么是云原生、怎么理解云相关概念,如有问题,欢迎指正。 一、云计算 定义:云计算是通过互联网(即“云”)按需提供计算资源(如服务器、存储、数据库、网络、软件等)的服…...

【数据结构】顺序表和链表详解(上)
前言:上期我们介绍了算法的复杂度,知道的算法的重要性同时也了解到了评判一个算法的好与坏就去看他的复杂度(主要看时间复杂度),这一期我们就从顺序表和链表开始讲起。 文章目录 一,顺序表1,线性表2,顺序表…...

唯创WT2606B TFT显示灵动方案,重构电子锁人机互动界面,赋能智能门锁全场景交互!
在智能家居的浪潮中,门锁搭载显示屏已成为行业创新的焦点。据行业数据显示,2023年全球智能门锁出货量中,搭载显示屏的型号占比已突破40%,且年复合增长率达25%。而2024年国内智能门锁销量突破2200万套,预计2025年市场规…...
WPF的UI交互基石:数据绑定基础
数据绑定基础 1 Binding的Path属性2 ElementName绑定3 DataContext的作用4 绑定模式(Binding Mode)5 实用技巧集合1. 默认值处理2. 设计时数据3. 绑定验证4. 多级路径监控 6 常见错误排查 数据绑定是WPF的核心特性之一,它实现了界面ÿ…...

智能穿戴新标杆:SD NAND (贴片式SD卡)与 SOC 如何定义 AI 眼镜未来技术路径
目录 一、SD NAND:智能眼镜的“记忆中枢”突破空间限制的存储革命性能与可靠性的双重保障 二、SOC芯片:AI眼镜的“智慧大脑”从性能到能效的全面跃升多模态交互的底层支撑 三、SD NANDSOC:11>2的协同效应数据流水线的高效协同端侧…...
TCP/IP四层模型
TCP/IP四层模型 TCP/IP四层模型将网络通信分为四个层次: 1. 网络接口层:负责计算机与网络硬件间的数据传输,在物理网络上发送/接收数据帧(如以太网、Wi-Fi协议)。 2. 互联网层(网络层)&…...
深入浅出Nacos:微服务架构中的服务发现与配置管理利器
在当今的软件开发领域,随着微服务架构的普及,如何有效地进行服务治理和服务配置管理成为了开发者面临的重要挑战之一。阿里巴巴开源的 Nacos(Dynamic Naming and Configuration Service)应运而生,旨在帮助开发者更轻松地构建云原生应用。本文将详细介绍 Nacos 的核心功能、…...

node_modules包下载不下来
如果项目里面的package-lock.json有resolved ,就指向了包的下载来源,如果这个网址挂了,那npm i 就会一直卡着。而且,在终端去修改 npm的镜像是没有用的 解决办法是:把项目里面的 lock文件 .npmrc都删了 然后重新下载就可以了...

yolo个人深入理解
卷积层的理解,通过云端服务器训练模型,模型构建的重要性,针对极低像素的处理,模型训练召回率提高技巧,卷积层2,4,8,16,32的小模型与大模型的理解 一.关于backbone,neck,head深入理解 1,backbone的主要组成部分是sppf和conv,这是backbone的核心,其中yolov5和yolov8…...
Go语言中的布尔类型详解
布尔类型是Go语言中最基本的数据类型之一,用于表示逻辑值。下面详细介绍Go语言中的布尔类型。 1. 基本概念 Go语言中的布尔类型用关键字bool表示,它只有两个预定义的常量值: true // 真 false // 假 2. 声明布尔变量 var b1 bool …...
三方接口设计注意事项
前言 随着业务系统间集成需求的增加,三方接口设计已成为现代软件架构中的关键环节。一个设计良好的三方接口不仅能够提供稳定可靠的服务,还能确保数据安全、提升系统性能并支持业务的持续发展。 一、设计原则 1. 统一接口原则 三方接口设计应遵循统一…...