首页 > 其他分享 >proto文件详解

proto文件详解

时间:2023-04-22 15:48:00浏览次数:38  
标签:文件 string int32 int age proto 详解 message name

一、message介绍

message:protobuf中定义一个消息类型是通过关键字message字段指定的。消息就算需要传输的数据格式的定义。message关键字类似于C++中的class,Java中的Class,go中的struct

例如:

message User{
	string username=1;
	int32 age=2;
}

在消息中承载的数据分别对应于每一个字段。

其中每个字段都有一个名字和一种类型。

二、字段规则

字段 作用
required 消息体中必填字段,不设置会导致编解码异常。一般不填就认为是必填字段了
optional 消息体中可选字段。生成的是对应的指针
repeated 消息体中可重复字段,重复的值的顺序会被保留,在go中重复的会被定义为切片

例子:

定义一个结构

message User{
	string username=1;
	int32 age=2;  
	optional string password=3;  // 生成的是指针
	repeated string address=4;  // 生产的是切片
}

生成一下执行protoc --go_out=./ .\user.proto

生成下面的文件

type User struct {
    state protoimpl.MessageState
    sizeCache protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    
    Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
    Age int32 `prtobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
    Password *string `protobuf:"bytes,3,opt,name=password,proto3,oneof" json:"password,omiyempty"`
    Address []string `protobuf:"bytes,4,rep,name=address,proto3" json:"address,omitempty"`
}

可以看到Address变成了一个切片

三、字段映射

.proto Type Notes C++ Type Python Type Go Type
double double float float64
float float float float32
int32 使用变长编码,对于负值的效率很低,如果你的域有 可能有负值,请使用sint64替代 int32 int int32
uint32 使用变长编码 uint32 int/long uint32
uint64 使用变长编码 uint64 int/long uint64
sint32 使用变长编码,这些编码在负值时比int32高效的多 int32 int int32
sint64 使用变长编码,有符号的整型值。编码时比通常的 int64高效。 int64 int/long int64
fixed32 总是4个字节,如果数值总是比总是比228大的话,这 个类型会比uint32高效。 uint32 int uint32
fixed64 总是8个字节,如果数值总是比总是比256大的话,这 个类型会比uint64高效。 uint64 int/long uint64
sfixed32 总是4个字节 int32 int int32
sfixed32 总是4个字节 int32 int int32
sfixed64 总是8个字节 int64 int/long int64
bool bool bool bool
string 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文 本。 string str/unicode string
bytes 可能包含任意顺序的字节数据。 string str []byte

四、默认值

protobuf3删除了protobuf2中用来设置默认值的default关键字,取而代之的是protobuf3为各类型定义的默认值,也就是约定的默认值,如下表:

类型 默认值
bool flase
整型 0
string 空字符串""
枚举enum 第一个枚举元素的值,因为Protobuf3强制要求第一个枚举元素的值必须是0,所以枚举的默认值就是0
message 不是null,而是DEFAULT_INSTANCE

五、标识号

标识号:在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[0.2^29-1]范围内的一个整数。

message User{
	string username=1;  // 位置1
	int32 age=2;
	optional string password=3;
	repeated string address=4;  // 位置4
}

以Person为例,name=1,id=2,email=3,phones=4中的1- 4就是标识号

六、定义多个消息队列

一个proto文件中可以定义多个消息类型

message UserRequest{
	string username=1;   // 位置1
	int32 age=2;
	optional string password=3;
	repeated string address=4;  // 位置4
}
message UserResponse{
	string username=1;
	int32 age=2;
	optional string password=3;
	repeated string address=4;
}

七、嵌套消息

可以在其他消息类型中定义,使用消息类型,在下面的例子中,Person消息就定义在PersonInfo消息内

message PersonInfo{
	message Person{
		string name=1;
		int32 height=2;
		repeated int32 weight=3;
	}
	repeated Person info=1;
}

如果你想在它的父消息类型的外部重用这个消息类型,你需要以PersonInfo.Person的形式来使用它,如:

message PersonMessage{
	PersonInfo.Person info=1;
}

当然也可以消息嵌套多层,比如

message Grandpa {
	message Father {
		message Son{
			string name=1;
			int32 age=2;
		}
	}
	message Uncle{
		message Son{
			string name=1;
			int32 age=1;
		}
	}
}

八、定义服务

如果想要将消息类型用在rpc系统中,可以在.proto文件中定义一个rpc服务接口,protocolbuffer编译器会根据所选择的不同语言生成服务接口代码及存根。

service SearchService{
	// rpc 服务的函数名(传入参数)返回(返回参数)
    rpc Search(UserRequest) returns(UserResponse);
}

上述代表表示,定义了一个RPC服务,该方法接收SearchRequest返回SearchResponse

参考:

标签:文件,string,int32,int,age,proto,详解,message,name
From: https://www.cnblogs.com/oaoa/p/17343163.html

相关文章

  • nginx配置文件
    关于Nginx的核心配置文件nginx.confusernginx;worker_processesauto;error_log/var/log/nginx/error.lognotice;pid/var/run/nginx.pid;events{worker_connections1024;}http{include/etc/nginx/mime.types;default_typeapplication/oct......
  • Java中的String的intren方法详解
    intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池Stringa=newString("hello").intern();Stringb="hello";System.out.println(a==b);//Stringa=newString("hello");a.intern();Stringb="hello";System.out.println(a==b)......
  • 如何把Mac上的文件传输到Windows电脑上
    前提是两台电脑在同一个局域网内!!!!1、在Windows上新建共享文件夹 2、打开Windows的smb共享支持3、打开访达->前往->连接服务器4、点击“连接”,成功后访达左边菜单栏就会出现Windows的共享文件夹5、把MAC里的文件就可直接拖动至Windows共享的文件夹里,Windows上就可以看到......
  • 手写 PE 文件
    手写PE文件此内容是逆向工程实验内容,对应完整PE文件结构更加复杂此处是借助C语言完成的,因为真正手写没有意义真正手写查错困难核心目的是了解PE文件的大概结构#include<stdio.h>#include<stdlib.h>#include<string.h>#include<windows.h>#include<winnt......
  • 文件管理
    要实现文件管理功能,我们可以使用toga.FileDialog控件来选择文件和文件夹,使用os模块来操作文件。以下是一个简单的文件管理器的代码示例:importosimporttogaclassFileManager:  def__init__(self):    self.main_window=toga.MainWindow(title='FileManager......
  • 企业网盘文件管理介绍
    在当今的数字时代,数据存储和管理已经成为任何商业组织的重要组成部分。随着云技术的出现,企业现在可以在世界任何地方存储和访问他们的数据。企业网盘工具就是一个不错的文件解决方案~ZohoWorkdrive是一个在线文件存储和协作平台,旨在简化团队的文档管理。它提供安全可靠的文件共享......
  • SQL注入,命令注入,文件操作
    SQLInjection:是一种常见的Web安全漏洞,gongji者利用这个漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行gongji所谓的万能密码:本质上就是SQL注入的一种利用方式一次SQL注入的过程:1.获取用户请求参数         2.拼接到代码当中3.SQL语句按照我们构造参数的语......
  • C++调用自定义源文件函数
    C++调用自定义源文件函数的步骤如下:在需要调用函数的源文件中包含自定义源文件的头文件。例如,如果需要调用名为myfunc.cpp的自定义源文件中的函数,则需要在调用该函数的源文件中包含myfunc.h头文件。编译自定义源文件。如果使用命令行编译,可以使用以下命令编译自定义源文件并生成......
  • django实现文件上传、删除、下载
    django文件上传定义一个包含FileFiled的类ModelWithFileField,其中upload字段的upload_to参数表示上传的文件存放在什么地方classModelWithFileField(models.Model):filename=models.CharField(max_length=100,verbose_name="文件名称")upload_date=models.Date......
  • # jquery # form表单上传文件
    form表单上传文件<formaction="/upload/"method="post"enctype="multipart/form-data">头像:<inputtype="file"name="head-pic">用户名:<inputtype="text"name="username">......