Proto GO使用教程

一、文件内构成

syntax = "proto3"; //proto版本
package api;   //生成文件的包名

/*
 简单的demo
 段落注释
 */

//数据结构 行注释
message Persion {
    int64 name = 1;
    int64 age = 3;
}

1.syntax 需要在文件内指定版本
2.package 生成文件在文件内显示的包名
3.注释方式 //和/*/
4.message 消息结构
消息字段需要指定 类型字段名字段编号

1.字段编号

  • 1.字段编号必须是唯一的,一旦使用了消息类型,就不应更改这些字段号(请提前预留你要使用的字段号),删除字段的标号不要重新使用

  • 2.范围为1到15的字段号需要一个字节来编码,包括字段号和字段的类型(您可以在Protocol Buffer Encoding中找到有关此内容的更多信息)。16到2047之间的字段编号占用两个字节。因此,您应该为经常出现的消息元素保留数字1到15。请记住为将来可能添加的频繁出现的元素留出一些空间。

  • 3.字段编号范围 1-最大为2的29次方 - 1(536870911) 其中19000-19999是不能使用的

  • 4.保留字段 如果你删除一个字段或者注释一个字段,而且这个字段你之后还会再用到,则将已删除字段的字段编号(和/或名称,也可能导致JSON序列化的问题)指定为reserved。如果将来有任何用户尝试使用这些字段标识符,则协议缓冲区编译器会报错。请注意,您不能在同reserved一条语句中混用字段名称和字段编号。

    message Foo {
      reserved 2, 15, 9 to 11;
      reserved "foo", "bar";
    }
    

2.字段规则

字段规则有以下两种

  • 1.singular :一个message可以有一个或者0个该规则类型字段(默认字段规则,但是直接声明singula会报错,求指导原因)

  • 2.repeated:一个message可以有任意个该规则类型字段(数组)

    repeated int64 num = 1; => Num []int64

3.字段类型

详情见https://developers.google.com/protocol-buffers/docs/proto3

4.默认值

  • string:空字符串.
  • bytes, 空bytes.
  • bools, false.
  • numeric types, 0.
  • enums:默认值为第一个定义的枚举值,必须为0.
  • For message fields, the field is not set. Its exact value is language-dependent. See the generated code guide for details.

proto3 go_out 默认生成的文件的基本类型会在json里面加入omitempty
即0值默认为空数据

JobId     uint64  `protobuf:"fixed64,3,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`

如果希望保留默认值(在结构转bytes的时候保留0值数据,需要去掉omitempty)
ls api/*.pb.go | xargs -n1 -IX bash -c ‘sed s/,omitempty// X > X.tmp && mv X{.tmp,}’

5.文件导入

目录结构如下:
proto-test

  • proto1
    – Makefile
    – person.proto
    –student.proto
  • proto2
    –pet.proto
syntax = "proto3";//使用版本
package person;

/*
 简单的demo
 段落注释
 */
//人
message Person {
    repeated   int64 name = 1;
    int64 age = 3;
}
syntax = "proto3";//使用版本
package person;

import "person.proto";

message Student {
    Person base = 1;
}

1.包内引用:

在同一个包下,直接使用文件名导入,person和student 在同一个package person;下所以直接引用,在makefile的时候直接以下命令执行,即不需要指定输入文件信息.

protoc  --go_out=. *.proto

2.跨包引用

syntax = "proto3";//使用版本
package person;

/*
 简单的demo
 段落注释
 */
//人
message Person {
    repeated   int64 name = 1;
    int64 age = 3;
}
syntax = "proto3";//使用版本
package person;

import "person.proto";
import "proto2/pet.proto";

message Student {
    Person base = 1;
    pet.Pet pet1 = 2;
}
syntax = "proto3";//使用版本
package pet;


message Pet {
    int64 name = 1;
    int64 age = 3;
}
  • 1.显示输入文件

student.proto里面引用proto2里面的pet.proto,所以在makefiles的时候需要指定输入的文件信息

protoc   -I "./" -I "../" --go_out=. *.proto

上面的命令是指输入文件是本目录 和上一级目录

  • 2.import的目录是和-I的路径相对应的 这里 import “proto2/pet.proto”;是ok的,

    如果import “proto-test/proto2/pet.proto”;

    会提示 Import “proto-test/proto2/pet.proto” was not found or had errors.

  • 3.如果总是提示找不到文件

    cd …(-I “…/” )出现的是要引用的文件目录是:proto2 所以import的时候 import “proto2/pet.proto”

二、命令解析

protoc --go_out=. *.proto -I ./

–go_out=有两个参数
参数1 是结果输出的目录,参数2是proto目标文件的目录
-I 在输出目录下生成文件时替换部分目录
例如目录结构如下
python/demo/protoTest/people.proto
在python 目录下执行

 protoc  --go_out=./demo/protoTest/ ./demo/protoTest/*.proto   -I ./demo/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Go 中使用 Protocol Buffers(简称 proto)可以通过以下步骤进行: 1. 安装 protoc 编译器:Protocol Buffers 使用 protoc 编译器将 .proto 文件编译成 Go 代码。你可以从 [Protocol Buffers GitHub 仓库](https://github.com/protocolbuffers/protobuf/releases) 下载适合你操作系统的 protoc 编译器,并将其添加到系统 PATH 环境变量中。 2. 编写 .proto 文件:创建一个名为 example.proto 的文本文件,并使用 Protocol Buffers 的语法定义消息结构和服务。 示例 example.proto 文件: ```protobuf syntax = "proto3"; package example; message Person { string name = 1; int32 age = 2; repeated string hobbies = 3; } service Greeting { rpc SayHello (Person) returns (Person); } ``` 3. 生成 Go 代码:使用 protoc 编译器将 .proto 文件生成 Go 代码。在终端中运行以下命令: ```shell protoc --go_out=. example.proto ``` 这将在当前目录下生成一个 example.pb.go 文件,其中包含了根据 .proto 文件生成的 Go 结构体和服务代码。 4. 在 Go 代码中使用生成的代码:在你的 Go 代码中导入生成的代码文件,并使用其中定义的结构体和服务进行编程。 示例 Go 代码: ```go package main import ( "fmt" "log" example "path/to/generated/code" // 导入生成的代码包 "google.golang.org/protobuf/proto" ) func main() { person := &example.Person{ Name: "John", Age: 25, Hobbies: []string{"reading", "coding"}, } data, err := proto.Marshal(person) if err != nil { log.Fatal(err) } // 在这里可以将 data 发送给其他地方进行传输或存储 newPerson := &example.Person{} err = proto.Unmarshal(data, newPerson) if err != nil { log.Fatal(err) } fmt.Println(newPerson.GetName()) // 输出:John } ``` 以上就是使用 Protocol Buffers 在 Go 中的基本步骤。你可以根据自己的需求定义更复杂的消息结构和服务,并使用生成的 Go 代码进行序列化、反序列化等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值