protobuf文件编写在goland gomod下正确姿势探究,由浅入深版(版本proto3)

swiftlc · · 1830 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

### protobuf文件编写在goland gomod下正确姿势探究,由浅入深版(版本proto3) ------ #### 测试环境准备 1. protoc执行文件 https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.3 2. protoc-gen-go **go get github.com/golang/protobuf/{proto,protoc-gen-go}** ![12313](https://img-blog.csdnimg.cn/20200618035825199.png) 3. 启动GOLAND 创建**go module**项目 #### proto文件名,package与option go_package ###### 单文件测试 文件名,package,以及option go_package对生成文件内容的影响 1. 编写proto文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618035903604.png) 2. 使用命令 `protoc -I . --go_out=. test.proto` 生成.go文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618035921258.png) 3. 修改proto文件,增加package项 `package` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618035936457.png) 4. 使用命令 `protoc -I . --go_out=. test.proto` 生成.go文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618035948808.png) 5. 再次修改proto文件,增加 `option go_package`项 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040000144.png) 6. 使用命令 `protoc -I . --go_out=. test.proto` 生成.go文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040011428.png) 结论 > 作用 **option go_package > package > 文件名** 对 生成go文件package内容的影响,其中proto文件名还影响最终生成go文件名。 更多的package,以及option go_package内容如何影响到最终生成go文件package内容 1. 移除`option go_package`,修改 `package` 内容为 `package test1.test2;` *(tip:package内容不能使用目录分隔符)* ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040026286.png) 2. 使用命令 `protoc -I . --go_out=. test.proto` 生成.go文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040037407.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) **最终生成的go文件package为proto文件声明的package . 转换 _连接形式** 3. 增加 `option go_package` 选项 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040053868.png) 4. 同样生成 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040103445.png) **嗯,和package效果类似** 5. 那如果这样呢,使用目录分隔符 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040114999.png) 6. 同样使用命令 ``protoc -I . --go_out=. test.proto`` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040126407.png) 此时结果和之前大有不同 1. 命令根据 `option go_package` 设置的内容在`protoc --go_out=指定的目录(这个可以去测试)`下创建了目录结构 `test3/test4` 2. 最终生成的文件放在 `test3/test4`目录下,并且使用`test4作为go文件package名` 3. 那 这么看 `package`好像已经没什么鸟用了? ###### 多文件引用测试 > 准备 > > 1. 可选: 在GOLAND中安装protobuf语法提示插件 > > ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040145420.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) > > 2. 修改`test.proto`文件,增加`message` > > ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040157475.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 本地多文件引用测试 1. 增加`test2.proto`文件,并填入如下内容 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040208594.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) **发现在语法提示插件并不能识别到本地的proto文件包含,缺少语法提示** 解决: **GOLAND->设置->搜索protobuf** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040220315.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 完成上述过后 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040230886.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040239492.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) **发现proto文件的`package`还是有用的,在proto文件相互引用时,可以充当`命名空间`的作用** 2. 使用命令 `protoc -I . --go_out=. test2.proto` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040251242.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 清晰版:![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040303317.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 目录结构生成和之前类似 **go文件包引用采用的是 被引用proto文件的`option go_package`选项内容** 3. 继续,移动`test.proto`文件到目录`randomDir`下 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040315562.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 4. 再次打开`test2.proto`文件,发现语法`报错` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040325454.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 5. 修正语法错误 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040334535.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 6. 使用命令 `protoc -I . --go_out=. test2.proto` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040343718.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 结果未变 到这里总结一下吧 > 1. proto文件引入是从某些配置的目录下进行文件查找定位 > > 如果是语法检查器,则按上面修改GOLAND protobuf相关配置添加相应目录即可 > > 如果是protoc命令工具,则添加 `-I` 选项指定目录 > > 2. 一旦多个proto文件被正确import,后面实际在使用的过程中,proto文件的`package`选项可作为`命名空间`使用来区分究竟引用的是`哪个proto文件`的`哪个message`。 *不过上面操作产生的go文件并不能正常运作,正常情况下不同目录的包引用应该是从$GOPATH目录往下* ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040358363.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) ------ **上面说了那么多,现在给出一个GOLANG编写proto文件的正确姿势** > 1. GOLAND新建GO MODULE项目,修改项目设置(`不使用语法提示可以不设置`) > >![在这里插入图片描述](https://img-blog.csdnimg.cn/2020061804044412.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) > > 2. 按照项目需求在不同目录下编写proto文件,但`option go_package`要使用`以项目名开始的目录分隔形式`, `package`用作`命名空间`,可以按需命名 > > ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040457457.png) > > 3. 使用`protoc命令`生成go文件按如下格式编写 > > ```shell > # 前提,protoc命令执行目录是项目目录 > > protoc -I .. -I . [其他选项] --go_out=.. [如果还有micro --micro_out=..] (proto文件路径) > > 比如,上述生成p1.proto文件 > protoc -I .. -I . --go_out=.. dir1/p1.proto > ``` > > ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040510217.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) > > 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`来说明 1. 执行 `go mod vendor`,项目目录下将生成**vendor文件夹** 2. 设置语法提示(可选): ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040536513.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 3. 编写proto文件引入外部框架的proto文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040655677.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) 4. 生成脚本添加 `-I ./vendor/`即可,`protoc -I .. -I . -I ./vendor --go_out=.. test.proto` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200618040715851.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N3aWZ0bGM=,size_16,color_FFFFFF,t_70) *一切工作正常! 唉,坑啊*

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1830 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传