Golang中BrokenImport无法加载包的问题如何解决
Golang中BrokenImport无法加载包的问题如何解决 大家好,
我正在尝试理解如何创建和导入包,但不太确定发生了什么,以及为什么它试图从 GOROOT 而不是我的 GOPATH 加载自定义包:

backend@Colton MINGW64 ~/Documents/goworkspace/src/golang-book/chapter11
$ go run main.go
main.go:5:2: package golang-book/chapter11/math is not in GOROOT (C:\Program Files\Go\src\golang-book\chapter11\math)
backend@Colton MINGW64 ~/Documents/goworkspace/src/golang-book/chapter11
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=C:\Users\backend\Documents\goworkspace\bin
set GOCACHE=C:\Users\backend\AppData\Local\go-build
set GOENV=C:\Users\backend\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\backend\Documents\goworkspace\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\backend\Documents\goworkspace
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.17.5
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\backend\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\backend\AppData\Local\Temp\go-
我有一个名为 math.go 的文件,其相对路径为 chapter11\math\math.go,代码看起来如下(尽管我怀疑这与我所遇到的错误无关…):
package math
func Average(xs []float64) float64 {
total := float64(0)
for _, x := range xs {
total += x
}
return total / float64(len(xs))
}
更多关于Golang中BrokenImport无法加载包的问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这是事情的工作原理:首先检查 GOROOT,然后是 GOPATH。
相对路径永远不会以这种方式被考虑。在旧的 Go 版本中,有一种使用 ./foo/bar 的方式,不确定现在是否还允许,当时它就已经会产生警告了……
一种方法是在 GOPATH 内重新创建相同的结构,这样一切就应该都能找到了。
更好的方法是正确使用模块,并在 GitHub 或 GitLab 仓库下使用“命名空间”来组织内容。
更多关于Golang中BrokenImport无法加载包的问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我明白了,如果我不想使用GitHub来管理包,只想在本地创建包,该怎么办?
另外,既然Go会先检查GOROOT路径,然后再检查GOPATH,为什么当我在math文件夹中运行go install时,它没有安装到GOROOT中呢?
我参考了这里的示例: https://www.golang-book.com/books/intro/11#section1
那么,这不再是正确的做法了吗?您能否提供一些易于理解、不那么晦涩的文档?
这本书似乎是2012年的,距今已有9到10年。5年前我开始学习Go时,GOPATH仍是主流,但大约两年后被模块取代,如今已不再推荐使用。
因此,是的,按照书中描述的方式操作已不再是当前的做法。
你可以使用任何其他类似域名的命名空间作为模块名,但第一段必须像域名一样,包含由点分隔的“主机名”和顶级域名。
不过,GitHub和GitLab得到了Go编译器的“特殊支持”,编译器知道如何正确访问它们。最终,你也可以通过一些努力使用任何Git托管服务。
只要你遵循命名规则,确实可以完全在本地主机上操作,但我强烈建议不要这样做。
此外,go install不会安装到GOROOT中,因为GOROOT被视为标准库的位置且是不可变的。
只有Go更新才应该触及GOROOT。
NobbZ:
这本书似乎是2012年的,距今已有9到10年了。5年前我开始接触Go时,
GOPATH仍然是主流,但大约两年后就被模块(modules)取代了,并且现在已经过时了。所以,是的,按照书中描述的方式操作已经不是我们现在采用的方法了。
你可以为你的模块使用任何其他类似域名的命名空间,不过第一段必须像域名一样,由一个“主机名”和一个顶级域名组成,中间用点号分隔。
尽管GitHub和GitLab受到了Go编译器的“眷顾”,它知道如何正确访问它们。最终,通过一些努力,你可以使用任何Git托管服务。
只要你遵循命名规则,你确实可以完全在本地主机上操作,但我强烈建议不要这样做。
另外,
go install不会安装到GOROOT中,因为那里被认为是标准库的位置,并且是不可变的。只有Go更新才应该触及
GOROOT。
非常感谢提供这些信息!!
从你的 go env 输出可以看到 GO111MODULE= 为空,这表示启用了模块感知模式。问题在于你的项目目录 C:\Users\backend\Documents\goworkspace\src\golang-book\chapter11 中存在 go.mod 文件(由 GOMOD=C:\Users\backend\go.mod 指向),但你的导入路径 golang-book/chapter11/math 与模块路径不匹配。
首先检查你的 go.mod 文件内容:
cat C:\Users\backend\go.mod
如果模块声明是 module example.com/mymodule,那么导入应该使用完整模块路径:
// main.go
package main
import (
"fmt"
"example.com/mymodule/chapter11/math" // 使用完整的模块路径
)
func main() {
xs := []float64{1, 2, 3, 4}
avg := math.Average(xs)
fmt.Println(avg)
}
或者,如果你想要使用相对导入,可以这样组织项目结构:
goworkspace/
├── go.mod
└── chapter11/
├── main.go
└── math/
└── math.go
go.mod 内容:
module golang-book/chapter11
go 1.17
main.go 导入:
package main
import (
"fmt"
"golang-book/chapter11/math"
)
func main() {
xs := []float64{1, 2, 3, 4}
avg := math.Average(xs)
fmt.Println(avg)
}
运行命令:
cd C:\Users\backend\Documents\goworkspace\src\golang-book\chapter11
go run main.go
如果仍然有问题,尝试初始化正确的模块:
cd C:\Users\backend\Documents\goworkspace\src\golang-book\chapter11
go mod init golang-book/chapter11
go mod tidy
go run main.go
对于你的 math/math.go 文件,确保它在正确的目录中:
// chapter11/math/math.go
package math
func Average(xs []float64) float64 {
total := float64(0)
for _, x := range xs {
total += x
}
return total / float64(len(xs))
}

