我正在关注Protocol Buffer for Go tutorial,但我遇到以下问题:
syntax = "proto3"; package tutorial; message Person { string name = 1; ... }
确切地说会发生什么:我指定--go_out
与我的原型定义相同:(protoc --go_out=. addressbook.proto
)
然后在同一个文件夹中,我用这些简单的行创建了一个test.go:
package main
import "tutorial"
但go build test.go
会返回错误:
test.go:3:8: cannot find package "tutorial" in any of:
/usr/local/go/src/tutorial (from $GOROOT)
/home/vagrant/go2/src/tutorial (from $GOPATH)
然后我将test.go
更改为:
package main
import "protobufs/tutorial"
并收到此错误:
test.go:3:8: cannot find package "protobufs/tutorial" in any of:
/usr/local/go/src/protobufs/tutorial (from $GOROOT)
/home/vagrant/go2/src/protobufs/tutorial (from $GOPATH)
但如果我将导入更改为:
package main
import "protobufs"
它发现该位置有一个“教程”包:
test.go:3:8: found packages tutorial (addressbook.pb.go) and main (list_people.go) in /home/vagrant/go2/src/protobufs
我做错了什么?为了使这项工作,导入应该如何?
谢谢!
仅供参考:我的环境片段:
GOARCH="amd64"
GOBIN="/home/vagrant/go2/bin"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/vagrant/go2"
GORACE=""
GOROOT="/usr/local/go"
答案 0 :(得分:1)
这个问题表明我对Go的包装缺乏了解。经过一番阅读,这是我的结论/规则:
1.每个文件夹一个包:目录“ abc ”中的所有.go文件将指示package abc
2.您不能将包main
和包abc
放在同一个文件夹中
3. go install
在abc.a
中创建包对象$GOPATH/pkg/GOOS_GOARCH/<path_to_abc_excluding_abc>
4.对于文件夹main
中的包$GOPATH/src/x/y/z/foo/
,然后go install
在foo
中编译并安装名为$GOPATH/bin
的可执行文件(路径中最后一个目录的名称) }
现在,回到最初的问题:目录$GOPATH/src/protobufs
包含多个包:
- 已编译的protobuf,包名为tutorial
和
- main
中的test.go
包裹
这与上面列出的规则相矛盾。
我相信一个优雅的解决方案是:
- 假设我在$GOPATH/src/protobufs
- 创建一个名为tutorials
的子目录
- 在该子目录中安装已编译的protobuf:protoc --go_out=./tutorial ./addressbook.proto
- test.go
现在可以package main
和import "protobufs/tutorial"
感谢您走上正轨!
答案 1 :(得分:0)
检查GO workspace:
A workspace is a directory hierarchy with two directories at its root:
src contains Go source files, and
bin contains executable commands.
本教程基于这种结构,即
src/
github.com/protocolbuffers/protobuf/examples/
tutorial/
addressbook.pb.go
list_address.go
在该教程的 makefile 中,它通过以下方式在 pb.go
目录下生成 examples
:
mkdir -p tutorial
protoc $$PROTO_PATH --go_out=tutorial addressbook.proto
在add_person.go下,它只是假设导入路径在worksapce/src
下,也就是上面提到的$GOPATH/src
:
import (
....
pb "github.com/protocolbuffers/protobuf/examples/tutorial"
// find through $GOPATH/src/github.com/protocolbuffers/protobuf/examples/tutorial
)
您需要做的是设置正确的 GOPATH
并在 pb.go
$GOPATH/src
protoc -I=. --go_out=/Users/guihaoliang/Playground/go/my_workspace/src addressbook.proto
其中 .
指的是 addressbook.proto
所在的位置。
GOPATH
工作区将被 go modules 取代,因此您不必维护 src
和 bin
结构。 protobuf 示例未使用新的模块结构。