protobuf文件编写在goland gomod下正确姿势探究,由浅入深版(版本proto3)
测试环境准备
protoc执行文件
https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.3
protoc-gen-go
go get github.com/golang/protobuf/{proto,protoc-gen-go}
启动GOLAND 创建go module项目
proto文件名,package与option go_package
单文件测试
文件名,package,以及option go_package对生成文件内容的影响
编写proto文件
使用命令
protoc -I . --go_out=. test.proto
生成.go文件修改proto文件,增加package项
package
使用命令
protoc -I . --go_out=. test.proto
生成.go文件再次修改proto文件,增加
option go_package
项使用命令
protoc -I . --go_out=. test.proto
生成.go文件
结论
作用 option go_package > package > 文件名 对 生成go文件package内容的影响,其中proto文件名还影响最终生成go文件名。
更多的package,以及option go_package内容如何影响到最终生成go文件package内容
移除
option go_package
,修改package
内容为package test1.test2;
(tip:package内容不能使用目录分隔符)使用命令
protoc -I . --go_out=. test.proto
生成.go文件最终生成的go文件package为proto文件声明的package . 转换 _连接形式
增加
option go_package
选项同样生成
嗯,和package效果类似
那如果这样呢,使用目录分隔符
同样使用命令
protoc -I . --go_out=. test.proto
此时结果和之前大有不同
- 命令根据
option go_package
设置的内容在protoc --go_out=指定的目录(这个可以去测试)
下创建了目录结构test3/test4
- 最终生成的文件放在
test3/test4
目录下,并且使用test4作为go文件package名
- 那 这么看
package
好像已经没什么鸟用了?
- 命令根据
多文件引用测试
准备
可选: 在GOLAND中安装protobuf语法提示插件
修改
test.proto
文件,增加message
本地多文件引用测试
增加
test2.proto
文件,并填入如下内容发现在语法提示插件并不能识别到本地的proto文件包含,缺少语法提示
解决: GOLAND->设置->搜索protobuf
完成上述过后
发现proto文件的
package
还是有用的,在proto文件相互引用时,可以充当命名空间
的作用使用命令
protoc -I . --go_out=. test2.proto
清晰版:
目录结构生成和之前类似 go文件包引用采用的是 被引用proto文件的
option go_package
选项内容继续,移动
test.proto
文件到目录randomDir
下再次打开
test2.proto
文件,发现语法报错
修正语法错误
使用命令
protoc -I . --go_out=. test2.proto
结果未变
到这里总结一下吧
proto文件引入是从某些配置的目录下进行文件查找定位
如果是语法检查器,则按上面修改GOLAND protobuf相关配置添加相应目录即可
如果是protoc命令工具,则添加
-I
选项指定目录一旦多个proto文件被正确import,后面实际在使用的过程中,proto文件的
package
选项可作为命名空间
使用来区分究竟引用的是哪个proto文件
的哪个message
。
不过上面操作产生的go文件并不能正常运作,正常情况下不同目录的包引用应该是从$GOPATH目录往下
上面说了那么多,现在给出一个GOLANG编写proto文件的正确姿势
- GOLAND新建GO MODULE项目,修改项目设置(
不使用语法提示可以不设置
)
按照项目需求在不同目录下编写proto文件,但
option go_package
要使用以项目名开始的目录分隔形式
,package
用作命名空间
,可以按需命名
使用
protoc命令
生成go文件按如下格式编写# 前提,protoc命令执行目录是项目目录 protoc -I .. -I . [其他选项] --go_out=.. [如果还有micro --micro_out=..] (proto文件路径) 比如,上述生成p1.proto文件 protoc -I .. -I . --go_out=.. dir1/p1.proto
tips: 还可以利用find命令一次将项目目录下的所有proto文件全部生成
find ./ -type f -name '*proto' -exec protoc -I .. -I . --go_out=.. {} \;
有时候我们还需要引用到某些框架下面已经写好的proto文件,在go module上操作简直一堆幺蛾子,目前有一个解决方案
下面拿引入github.com/micro/go-micro/v2/api/proto
来说明
执行
go mod vendor
,项目目录下将生成vendor文件夹设置语法提示(可选):
编写proto文件引入外部框架的proto文件
生成脚本添加
-I ./vendor/
即可,protoc -I .. -I . -I ./vendor --go_out=.. test.proto
一切工作正常! 唉,坑啊
有疑问加站长微信联系(非本文作者))
