Go中的协议缓冲区:找不到包

时间:2017-05-05 23:36:48

标签: go protocol-buffers

我正在关注Protocol Buffer for Go tutorial,但我遇到以下问题:

  1. 我创建了地址簿原型定义
  2. syntax = "proto3";
    package tutorial;
    
    message Person {
      string name = 1;
    ...
    }
    
    1. 我成功运行编译器并生成go代码
    2. 我尝试导入pb包但它失败了
    3. 确切地说会发生什么:我指定--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"
      

2 个答案:

答案 0 :(得分:1)

这个问题表明我对Go的包装缺乏了解。经过一番阅读,这是我的结论/规则:
1.每个文件夹一个包:目录“ abc ”中的所有.go文件将指示package abc
2.您不能将包main和包abc放在同一个文件夹中 3. go installabc.a中创建包对象$GOPATH/pkg/GOOS_GOARCH/<path_to_abc_excluding_abc> 4.对于文件夹main中的包$GOPATH/src/x/y/z/foo/,然后go installfoo中编译并安装名为$GOPATH/bin的可执行文件(路径中最后一个目录的名称) }

现在,回到最初的问题:目录$GOPATH/src/protobufs包含多个包:
- 已编译的protobuf,包名为tutorial
- main中的test.go包裹 这与上面列出的规则相矛盾。

我相信一个优雅的解决方案是:
- 假设我在$GOPATH/src/protobufs - 创建一个名为tutorials的子目录 - 在该子目录中安装已编译的protobuf:protoc --go_out=./tutorial ./addressbook.proto
- test.go现在可以package mainimport "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 取代,因此您不必维护 srcbin 结构。 protobuf 示例未使用新的模块结构。