欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 【go语言】protobuf 和 grpc

【go语言】protobuf 和 grpc

2025/2/5 9:03:37 来源:https://blog.csdn.net/2301_77868664/article/details/145419382  浏览:    关键词:【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.protomessage 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 可以帮助将它们封装在一起,减少不必要的重复定义。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com