【问题标题】:Error with Go modules build using /cmd structure使用 /cmd 结构构建 Go 模块时出错
【发布时间】:2018-11-03 00:59:37
【问题描述】:

我是新的模块,我正在尝试在一个新项目中试用它们,我试图按照here 描述的结构建模

这是我的目录结构示例:

.
├── cmd
│   └── app_name
│       └── main.go
├── go.mod
├── go.sum
├── internal
│   └── bot
│       └── bot.go
└── pkg
    ├── website_name
    │   ├── client.go
    │   ├── client.options.go
    │   ├── server.go
    │   └── server.options.go
    └── lib
        └── lib.go
  1. 这在惯用语上正确吗?我知道目前还没有很多共识,但我想遵循最佳做法。
  2. 当我运行 go build 时,我得到“意外的模块路径”github.com/ragurney/app_name/cmd/app_name”,但是当我运行 go build ./... 时它可以工作。为什么?

当我将 main.go 移动到顶层时,一切都按预期工作。我不应该将/cmd 模式与模块一起使用吗?

【问题讨论】:

  • go.mod 中的module 行是什么?听起来它指的是cmd/app_name,这是不正确的——它应该指向它所在的目录。
  • 它具体指向cmd/app_namemodule github.com/ragurney/app_name/cmd/app_name。所以应该是:github.com/ragurney/app_name?这样做会导致类似的错误:“找不到提供包 github.com/ragurney/app_name 的模块”
  • 是的,如果那是根目录(go.mod 文件所在的位置),它应该是 github.com/ragurney/app_name。您的仓库中是否偶然有多个 go.mod 文件?

标签: go go-modules


【解决方案1】:

要回答您的第一个问题,它完全是固执己见,而且您最喜欢的任何东西也很容易被其他人理解(我认为这很好)。

要回答您的第二个问题,go build ./... 与根目录中的go build 相比起作用的原因是,./... 从当前目录(根目录)开始并搜索所有程序入口点并构建它们。当您将 main.go 移动到根目录时,使用此新信息,go build 工作就有意义了,因为它只在当前目录中查找。

您可以明确地说go build ./cmd/app_name,这也可以。

您的应用程序结构与模块一起工作得非常好,因为我使用了与它非常相似的东西 (https://www.ardanlabs.com/blog/2017/02/package-oriented-design.html),并且模块对我来说工作得很好。

【讨论】:

  • 感谢您的详细回复,以及非常有用的资源链接!只是为了确认一下,如果我保留这个结构就可以了,然后我会用go mod init github.com/ragurney/app_name 初始化?然后每当我想生成二进制文件时,运行go build cmd/app_name/main.go?
  • 是的,这完全有效!
  • 正如答案所说,你会go build ./cmd/app_name。您构建的是一个 package,而不是 file,并且在 CWD 中将其作为 root 很重要(否则 go 认为您提供的是包名称,而不是路径)。跨度>
  • 明白了,感谢大家的所有帮助以及忍受我的愚蠢问题。今天学到了一些新东西:D
  • "...将其植根于 CWD 很重要..." @Adrian 你能指点我一个链接来描述/详细说明吗?我已经完成了go mod init github.com/ragurney/app_name,这似乎工作正常,尽管我的 cwd 类似于/Users/rygurney/Code/OtherDir/app_name
【解决方案2】:

据我所知,您的项目结构没有任何问题。对我有用的是从项目根目录运行 go build/run 命令

例如。 go run github.com/username/project/cmd/somecommand

go build -o somebinary github.com/username/project/cmd/somecommand

【讨论】: