Mit*_*lad 111 build package go
即使我已经GOPATH
正确设置,我仍然无法"go build"或"go run"来找到我自己的包.我究竟做错了什么?
$ echo $GOROOT
/usr/local/go
$ echo $GOPATH
/home/mitchell/go
$ cat ~/main.go
package main
import "foobar"
func main() { }
$ cat /home/mitchell/go/src/foobar.go
package foobar
$ go build main.go
main.go:3:8: import "foobar": cannot find package
Run Code Online (Sandbox Code Playgroud)
fas*_*mat 141
它不起作用,因为您的foobar.go
源文件不在名为的目录中foobar
.go build
并go install
尝试匹配目录,而不是源文件.
$GOPATH
为有效目录,例如export GOPATH="$HOME/go"
foobar.go
到$GOPATH/src/foobar/foobar.go
与建筑应该只是罚款.其他建议步骤:
$GOPATH/bin
你$PATH
的:PATH="$GOPATH/bin:$PATH"
main.go
到$GOPATH/src
例如的子文件夹$GOPATH/src/test
go install test
现在应该创建一个可执行文件$GOPATH/bin
,可以通过test
在终端中输入来调用.dev*_*ost 20
尽管关于需要将目录与包名称匹配的公认答案仍然是正确的,但您确实需要迁移到使用 Go 模块而不是使用 GOPATH。遇到此问题的新用户可能会对使用 GOPATH(就像我一样)的提及感到困惑,这些现在已经过时了。因此,我将尝试解决这个问题,并在使用 Go 模块时提供与防止这个问题相关的指导。
如果您已经熟悉 Go 模块并且遇到了这个问题,请跳到我下面更具体的部分,其中涵盖了一些容易忽略或忘记的 Go 约定。
本指南讲授 Go 模块:https : //golang.org/doc/code.html
使用 Go 模块组织项目
迁移到 Go 模块后,如该文章中所述,按所述组织项目代码:
一个存储库包含一个或多个模块。模块是一起发布的相关 Go 包的集合。Go 存储库通常只包含一个模块,位于存储库的根目录。一个名为 go.mod 的文件声明了模块路径:模块中所有包的导入路径前缀。该模块在包含其 go.mod 文件的目录中包含包以及该目录的子目录,直到包含另一个 go.mod 文件(如果有)的下一个子目录。
每个模块的路径不仅用作其包的导入路径前缀,而且还指示 go 命令应该在哪里下载它。例如,为了下载模块 golang.org/x/tools,go 命令将查询https://golang.org/x/tools指示的存储库(此处有更多描述)。
导入路径是用于导入包的字符串。包的导入路径是其模块路径与其在模块内的子目录相连。例如,模块 github.com/google/go-cmp 在目录 cmp/ 中包含一个包。该包的导入路径是 github.com/google/go-cmp/cmp。标准库中的包没有模块路径前缀。
你可以像这样初始化你的模块:
$ go mod init github.com/mitchell/foo-app
Run Code Online (Sandbox Code Playgroud)
您的代码无需位于 github.com 上即可构建。但是,将模块构建为最终将发布的结构是最佳实践。
了解尝试获取包裹时会发生什么
这里有一篇很棒的文章讨论了当您尝试获取包或模块时会发生什么:https : //medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16 它讨论了包的存储位置以及将如果你已经在使用 Go 模块,帮助你理解为什么你可能会收到这个错误。
确保导入的函数已经导出
请注意,如果您在从另一个文件访问函数时遇到问题,则需要确保已导出函数。如我提供的第一个链接中所述,函数必须以大写字母开头才能导出并可以导入到其他包中。
目录名称
另一个关键细节(如已接受的答案中所述)是目录名称定义了包的名称。(你的包名需要符合他们的目录名)。你可以在这里看到这样的例子:https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc
随着也就是说,包含您的main
方法(即您的应用程序的入口点)的文件在某种程度上不受此要求的约束。
例如,在使用这样的结构时,我的导入有问题:
/my-app
??? go.mod
??? /src
??? main.go
??? /utils
??? utils.go
Run Code Online (Sandbox Code Playgroud)
我无法将代码导入utils
到我的main
包中。
但是,一旦我放入main.go
它自己的子目录,如下所示,我的导入工作得很好:
/my-app
??? go.mod
??? /src
??? /app
| ??? main.go
??? /utils
??? utils.go
Run Code Online (Sandbox Code Playgroud)
在该示例中,我的 go.mod 文件如下所示:
module git.mydomain.com/path/to/repo/my-app
go 1.14
Run Code Online (Sandbox Code Playgroud)
当我在添加对 的引用后保存 main.go 时utils.MyFunction()
,我的 IDE 会自动拉入对我的包的引用,如下所示:
import "git.mydomain.com/path/to/repo/my-app/src/my-app"
Run Code Online (Sandbox Code Playgroud)
(我将 VS Code 与 Golang 扩展一起使用。)
请注意,导入路径包含包的子目录。
处理私人回购
如果代码是私有存储库的一部分,则需要运行 git 命令以启用访问。否则,您可能会遇到其他错误本文提到如何为私有 Github、BitBucket 和 GitLab 存储库执行此操作:https ://medium.com/cloud-native-the-gathering/go-modules-with-private-git- repositories-dfe795068db4 这里也讨论了这个问题:“获取”私有存储库的正确方法是什么?
Von*_*onC 10
编辑:既然你的意思是GOPATH,请参阅fasmat的回答(upvoted)
如" 我如何找到我的包? "中所述,您需要将包xxx
放在目录中xxx
.
请参阅Go语言规范:
package math
Run Code Online (Sandbox Code Playgroud)
共享相同的一组文件
PackageName
形成包的实现.
实现可能要求包的所有源文件都位于同一目录中.
该代码组织提到:
当构建导入包"
widget
"的程序时,该go
命令src/pkg/widget
在Go根目录中查找,然后 - 如果在那里找不到包源 - 它src/widget
按顺序搜索每个工作空间内部.
("工作区"是您的路径条目GOPATH
:该变量可以引用您的' src, bin, pkg
'的多个路径)
(原始答案)
你也应该设置 GOPATH
为〜/ go,而不是GOROOT
如" 如何编写Go代码 "中所示.
Go路径用于解析import语句.它由go/build包实现并记录.
该
GOPATH
环境变量列表地方寻找Go代码.
在Unix上,该值是以冒号分隔的字符串.
在Windows上,该值是以分号分隔的字符串.
在计划9中,值是一个列表.
这不同于GOROOT
:
Go二进制发行版假设它们将安装在
/usr/local/go
(或c:\Go
在Windows下),但可以将它们安装在不同的位置.
如果这样做,则需要GOROOT
在使用Go工具时将环境变量设置为该目录.
小智 10
我通过将 go env GO111MODULE 设置为 off 解决了这个问题
go env -w GO111MODULE=off
Run Code Online (Sandbox Code Playgroud)
在 1.14 之后的最新 go 版本中,我们必须go mod vendor
在构建或运行之前执行此操作,因为默认情况下 go 附加-mod=vendor
到 go 命令。所以做完之后go mod vendor
,如果我们尝试构建,我们就不会遇到这个问题。
归档时间: |
|
查看次数: |
172796 次 |
最近记录: |