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

【go语言】protobuf 和 grpc

一、protobuf 的基本类型和默认值

1.1 基本类型

       一个标量消息字段可以包含有一个如下的类型——该表格展示了定义于 .proto 文件中的类型,以及与之对应的、在自动生成的访问类中定义的类型:

  • 对于所有的情况,设定值会执行类型检查以确保此值是有效的
  • 64位或者无符号32位整形在解码时被表示为 long,但是在设置时可以使用 int 型值设定,在所有的情况下,值必须符合其设置其类型的要求

1.2 默认值

       当一个消息被解析的时候,如果被编码的信息部包含一个特定的 singular 元素,被解析的对象所对应的域被设置为一个默认值,对于不同类型指定如下:

  • 对于 strings,默认为一个空 string
  • 对于 bytes,默认为一个空的 bytes
  • 对于 bools,默认为 false
  • 对于数值类型,默认为 0
  • 对于枚举,默认为第一个定义的枚举值,必须为 0
  • 对于消息类型,域没有被设置,确切的消息是根据语言确定的
  • 对于可重复域的默认值是空

二、option go_package 的作用

   option go_package.proto 文件中指定生成的 Go 代码的包路径。它告诉 protoc 编译器生成的 Go 文件应该放在什么位置,并且应该使用哪个 Go 包名。这对 Go 开发者来说是非常重要的,因为它确保了生成的 Go 代码能够正确地与其他 Go 代码进行集成。

2.1 为什么需要 option go_package

  1. 确定包路径:Go 代码会根据这个选项来决定生成的 Go 文件放置的路径和包名,确保代码结构符合 Go 项目的标准结构。

  2. 避免冲突:如果多个 .proto 文件生成的 Go 代码没有正确指定 go_package,可能会发生包名冲突或无法正确导入其他生成的文件。

  3. 与 Go 代码整合go_package 还帮助 Go 工具链(比如 go getgo mod)正确识别和导入生成的代码。

       假设你有一个 .proto 文件 helloworld.proto,你希望生成的 Go 代码放在 github.com/yourusername/yourrepo/helloworld 包中。你可以在 .proto 文件中添加 go_package 选项:

syntax = "proto3";

package helloworld;

// 使用 go_package 指定 Go 包路径
option go_package = "github.com/yourusername/yourrepo/helloworld";

// 定义消息和服务
message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

2.2 option go_package的作用

  • 指定 Go 包路径option go_package = "github.com/yourusername/yourrepo/helloworld"; 指定了生成的 Go 文件会位于 github.com/yourusername/yourrepo/helloworld 包下。这样,你在其他地方导入这些 Go 文件时就可以使用该路径。

  • 帮助 Go 工具链:当使用 protoc 命令生成 Go 代码时,option go_package 会确保 Go 文件放到正确的位置,并且在 import 时能够正确解析路径。

2.3 使用 protoc 命令时的影响

生成 go 代码时,protoc 会根据 go_package 选项来决定生成的 go 文件的路径。里融入,使用以下命令生成 go 代码:

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld.proto

       生成的 Go 代码将会根据 go_package 中指定的路径生成。例如,Go 文件 helloworld.pb.go 将被放置在 github.com/yourusername/yourrepo/helloworld 包中。

三、proto 文件同步时的坑

       在进行编写 proto 文件的时候,我们需要将编号和变量一一对应,不能出现在不同目录下的同一个proto 文件出现不对等的情况,否则会出现一些错误。

四、proto 文件中 import 另一个文件

       在 proto 文件中,使用 import 语句可以导入其他 .proto 文件,这样就能使用其他文件中定义的消息类型,服务等。

       例如,假设有两个 proto 文件,file1.protofile2.proto,你想在 file2.proto 中使用 file1.proto 中定义的消息类型。

syntax = "proto3";

package example;

message Person {
  string name = 1;
  int32 id = 2;
}
syntax = "proto3";

package example;

import "file1.proto";  // 导入 file1.proto

message AddressBook {
  repeated Person people = 1;  // 使用 file1.proto 中的 Person 类型
}

需要注意:

  • import 语句可以是相对路径或绝对路径,具体取决于你的文件结构和编译时的配置。
  • 如果你导入的 .proto 文件在不同的目录中,你需要在 import 语句中指定相应的路径。

五、嵌套的 message 对象

       在 proto 文件中,嵌套的 message 对象是指在一个 message 类型内部定义另一个 message 类型。嵌套的 message 可以像其他普通的 message 一样被使用。

这种方式通常用于组织复杂的结构,方便保持数据结构的层级关系。

syntax = "proto3";

package example;

// 嵌套的 Address 类型
message Person {
  string name = 1;
  int32 id = 2;

  // 嵌套的 Address 类型
  message Address {
    string street = 1;
    string city = 2;
    string state = 3;
    string zip_code = 4;
  }

  Address address = 3;  // 使用嵌套的 Address 类型
}
  1. 嵌套 message:在 Person 类型内部定义了一个 Address 类型。这样,Address 就成为了 Person 的一部分。AddressPerson 类型的一个字段,它包含 streetcitystatezip_code 字段。

  2. 使用嵌套的 Address:在 Person 的字段中,我们可以直接使用嵌套的 Address 类型,就像普通的 message 一样。

  • 层级数据结构:适用于那些具有层次结构的数据模型。例如,表示人和地址时,地址是人数据的一部分,因此它可以嵌套在 Person 中。
  • 封装数据:当数据是逻辑上紧密关联的,嵌套的 message 可以帮助将它们封装在一起,减少不必要的重复定义。


http://www.kler.cn/a/534345.html

相关文章:

  • 使用Pygame制作“贪吃蛇”游戏
  • 导入了fastjson2的依赖,但却无法使用相关API的解决方案
  • C++ 学习:深入理解 Linux 系统中的冯诺依曼架构
  • 每日一题洛谷P5721 【深基4.例6】数字直角三角形c++
  • 解决threeJS加载obj gltf和glb模型后颜色太暗的方法
  • GitHub Copilot 越狱漏洞
  • mixin
  • STM32 串口收发数据包
  • 基于springboot+vue的青少年心理健康教育网站的设计与实现
  • Qt跨屏窗口的一个Bug及解决方案
  • FRP通过公网IP实现内网穿透
  • 日期选择控件,时间跨度最大一年。
  • springboot停车场管理系统设计与实现
  • 【高级篇 / IPv6】(7.2) ❀ 04. 在60E上配置ADSL拨号宽带上网(IPv4) ❀ FortiGate 防火墙
  • SQL 秒变三线表 sql导出三线表
  • Android studio ternimal 中gradle 指令失效(gradle环境变量未配置)
  • 表格文字的版面分析,PHP语言实现表格识别功能
  • 力扣hot100-双指针
  • 挑战项目 --- 微服务编程测评系统(在线OJ系统)
  • oracle 基础语法复习记录
  • 信息学奥赛一本通 2101:【23CSPJ普及组】旅游巴士(bus) | 洛谷 P9751 [CSP-J 2023] 旅游巴士
  • 4-ET框架demo的运行
  • react的antd表格自定义图标
  • 缓存类为啥使用 unordered_map 而不是 map
  • C# 国密算法
  • Linux 压缩打包