【问题标题】:How can I resolve dependencies in nested application binary in Go project?如何解决 Go 项目中嵌套应用程序二进制文件中的依赖关系?
【发布时间】:2019-02-15 03:56:30
【问题描述】:

这听起来很愚蠢,但我现在正在尝试构建我的新 golang 项目一段时间,但我遇到了以下错误

无法加载包:包 github.com/kuskmen/yamq/cmd/yamq-client:在 C:\projects\yamq\cmd 中找到包 main (main.go) 和 yamqclient (yamq-client.go) \yamq 客户端

我知道这应该很容易解决,但我来自 .NET,我仍然没有 Go 项目及其依赖解析模型的经验,因此很困难。

我的项目结构是这样的

/yamq
    /cmd
        /yamq-client          // yamq client application binary
            main.go           // package main
            yamq-client.go    // package yamqclient
        /yamq-server          // yamq server application binary
            main.go           // package main
            yamq-server.go    // package yamqserver
    go.mod                // contains only "module github.com/kuskmen/yamq" for now
    ... // some library files that will probably be moved to /shared folder

到目前为止一切顺利,当我在最外层目录 ( /yamq ) 中执行 go build 时,它正在成功构建(或者至少它没有显示任何错误),但是当我尝试构建 yamq-client 或 @987654326 时@binaries 我得到了上述错误,每次我尝试用谷歌搜索它或找到有用的东西时,我都会得到一些旧文章或答案,这些文章或答案可以追溯到 2013-2016 年,其中暗示了一些关于 $GOPATH 等的内容,因为这里不应该是这种情况我正在尝试使用 go 模块。

帮助 .NET 开发人员加入 Go 社区,向他解释模块的工作原理,因为我发现 thisthis 没用,或者至少我没有抓住重点,提前致谢!

【问题讨论】:

  • 如何从 main.go 导入 yamq-client?
  • 我试过 import “yamqclient” 和 import “github.com/kuskmen/yamq-client” 都给出了同样的错误:/
  • 路径应该反映您的文件系统路径。将其移出cmd - 没有理由,然后您将拥有github.com/kuskmen/yamq/yamqclient。还要将 yamq-client 重命名为 yamqclient 以保持一致性。一般来说,从其中一个教程中的单个 lib 结构开始,并在跳到两个单独的主目录之前使其工作
  • 硬性规则是 - 同一目录中的任何文件必须具有一致的包名称。因此,如果构建一个可执行文件 - 该目录中的所有文件都以 package main 开头。对于一个包 - pkg 目录中的所有文件都以package mypkgname 开头。您看到的错误是警告您在该特定构建目录中混合了 mainyamqclient 包名称。
  • @EliBendersky 我遵循 Go 项目模板指南,这就是为什么我将我的应用程序二进制文件放在 cmd 文件夹中,就像其他项目(kubernetes、heroku 等)一样

标签: go dependency-management go-modules


【解决方案1】:

从我上面的评论中跟进:

来自https://golang.org/doc/code.html

  • Go 程序员通常将所有 Go 代码保存在一个工作区中。
  • 一个工作区包含许多版本控制存储库(例如,由 Git 管理)。
  • 每个存储库都包含一个或多个包。
  • 每个包都包含一个或多个 Go 源文件,位于一个单个目录
  • 包目录的路径决定了它的导入路径。

【讨论】:

    【解决方案2】:

    对于您的项目,我会这样做:

    $ tree
    .
    ├── clientlib
    │   └── lib.go
    ├── cmd
    │   ├── client
    │   │   └── main.go
    │   └── server
    │       └── main.go
    ├── go.mod
    └── serverlib
        └── lib.go
    
    5 directories, 5 files
    
    $ cat go.mod
    module myproject.com
    

    模块名称是任意的(可以是github.com/yourname/yourproject)。

    对于服务器端:

    $ cat serverlib/lib.go 
    package serverlib
    
    import "fmt"
    
    func Hello() {
        fmt.Println("Hello from serverlib.Hello")
    }
    
    $ cat cmd/server/main.go 
    package main
    
    import (
        "fmt"
    
        "myproject.com/serverlib"
    )
    
    func main() {
        fmt.Println("Running server")
        serverlib.Hello()
    }
    

    现在我们可以构建并运行它了:

    $ go build -o server cmd/server/main.go 
    $ ./server
    Running server
    Hello from serverlib.Hello
    

    客户端看起来是对称的。

    变体:您可以在cmd/... 中使用它们的实际二进制名称命名.go 文件,例如server.goclient.go。每个中的包仍然是main,但随后go build 会创建一个具有文件名(没有.go)的可执行文件,而无需明确-o

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-16
      • 2017-05-14
      • 2017-09-07
      • 1970-01-01
      • 2016-06-04
      • 2012-02-14
      • 1970-01-01
      相关资源
      最近更新 更多