Golang中BrokenImport无法加载包的问题如何解决

Golang中BrokenImport无法加载包的问题如何解决 大家好,

我正在尝试理解如何创建和导入包,但不太确定发生了什么,以及为什么它试图从 GOROOT 而不是我的 GOPATH 加载自定义包:

Example

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

6 回复

这是事情的工作原理:首先检查 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))
}
回到顶部