Golang中GitHub和GoPkg的包版本不一致问题求助(新手提问)
Golang中GitHub和GoPkg的包版本不一致问题求助(新手提问)
从GitHub问题页面直接复制的内容
(后来我觉得这里可能是更合适的地方)
你使用的Go版本是什么(go version)?
$ go version
go version go1.14.2 linux/amd64
这个问题在最新版本中是否重现?
是
你使用的操作系统和处理器架构是什么(go env)?
Debian 10 Buster Stable,Intel® Pentium® G4600 (x86_amd64)
$ uname -a
Linux debian-homepc.bryanpedini.home 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1+deb10u1 (2020-04-27) x86_64 GNU/Linux
`go env` 输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bryanpedini/.cache/go-build"
GOENV="/home/bryanpedini/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/bryanpedini/projects/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build004077584=/tmp/go-build -gno-record-gcc-switches"
你做了什么?
目前正在尝试在家用开发PC上基于Echo框架实例实现一些API。 Go环境一直工作得很好(虽然我自己编码不多,我还在"标准库水平",所以以前从未需要使用版本化包),但现在它开始与包版本搞成一团乱麻。
我正在尝试执行的代码的简化版本:(没有ini配置文件和其它东西)
https://play.golang.org/p/IfCwkwtZAew(它不工作)
我的PC输出:
$ go get -u gopkg.in/labstack/echo.v4
$ go run main.go register.go user.go
../../../gopkg.in/labstack/echo.v4/middleware/basic_auth.go:8:2: cannot find package "github.com/labstack/echo/v4" in any of:
/usr/local/go/src/github.com/labstack/echo/v4 (from $GOROOT)
/home/bryanpedini/projects/go/src/github.com/labstack/echo/v4 (from $GOPATH)
$ go get -u github.com/labstack/echo/v4
package github.com/labstack/echo/v4: cannot find package "github.com/labstack/echo/v4" in any of:
/usr/local/go/src/github.com/labstack/echo/v4 (from $GOROOT)
/home/bryanpedini/projects/go/src/github.com/labstack/echo/v4 (from $GOPATH)
$ go get -u github.com/labstack/echo
$ go run main.go register.go user.go
# command-line-arguments
./main.go:13:38: cannot use middleware.RemoveTrailingSlash() (type "github.com/labstack/echo".MiddlewareFunc) as type "gopkg.in/labstack/echo.v4".MiddlewareFunc in argument to e.Pre
稍微修改的版本: https://play.golang.org/p/1PhlgeDA32V(它会超时,这清楚地告诉我Echo服务器启动了)
最后,同一段代码在我电脑上的结果(基本上只是更改了导入):
$ go run main.go register.go user.go
main.go:7:2: cannot find package "github.com/labstack/echo/v4" in any of:
/usr/local/go/src/github.com/labstack/echo/v4 (from $GOROOT)
/home/bryanpedini/projects/go/src/github.com/labstack/echo/v4 (from $GOPATH)
main.go:8:2: cannot find package "github.com/labstack/echo/v4/middleware" in any of:
/usr/local/go/src/github.com/labstack/echo/v4/middleware (from $GOROOT)
/home/bryanpedini/projects/go/src/github.com/labstack/echo/v4/middleware (from $GOPATH)
在VSCode的linter(微软官方的Go扩展)中,我得到相同的"无法导入github/labstack/echo/v4(没有github/labstack/echo/v4的包)"…
最后但同样重要的是,让我们尝试不带版本号,好吗?Linter vs 编译器… 战斗开始: linter首先发起攻击

然后Echo微服务器将linter击倒KO,因为它实际上运行良好… 就像,什么情况?
你期望看到什么?
一个易于使用的版本控制系统叫做gopkg.in
你实际看到了什么?
一团我无法描述的 几乎从不工作的混乱,带有难以猜测的导入路径,有时工作,有时不工作(而且由于谷歌搜索功能的错误,普遍缺乏对我问题的理解:你愚蠢的AI没理解"我可以从github导入go包但不能从gopkg导入"的哪部分?就找到我2003年的论坛帖子,好吗?引用:古人的智慧)
GitHub问题复制结束
在我深入探索之前,还有什么我应该尝试/需要知道的吗?或者因为我对Go包工作原理的(不/错误)理解而遭受更多头痛? 有没有人知道像指南或容易"进入思维体系"的东西?因为语言本身相当直接,非常像Cpp,而且(对我来说)容易开始理解和立即编写… 但是技术方案,伙计!!把文件放在"src"文件夹里,然后是一个以git平台命名的目录,接着是你的用户名,最后是项目名称,嗯,这很容易;但是如果我曾经理解过我观看的每个教程中关于包、它们的结构和导入方案的任何一点(现在比以往任何时候都更甚,随着包模块版本化的(几乎)新引入)…
提前感谢大家,对这篇长文表示抱歉(如前所述,这是从GitHub问题模板复制的,非常详细)。
更多关于Golang中GitHub和GoPkg的包版本不一致问题求助(新手提问)的实战教程也可以访问 https://www.itying.com/category-94-b0.html
欢迎来到 Go 论坛 🚀 🎆
在整体回答问题之前:当你进行原型开发时,你是在 go 模块内部进行开发吗?
编辑:你的项目目录中应该有一个 go.mod 文件。
// 代码示例应放在这里,但原文未提供具体代码
更多关于Golang中GitHub和GoPkg的包版本不一致问题求助(新手提问)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的……
现在,在到处执行了一些 go mod init 和 go mod tidy 之后,代码和 linter 都运行正常了。
我仍然不明白的是,为什么在用 go mod tidy 生成 go.mod 和 go.sum 文件之前,同样的导入(在这个例子中是 github.com/labstack/echo/v4)会报错,而没有版本号时却能工作;但现在即使加上版本号也能工作了……
这到底是怎么回事?我的意思是,如果是因为 go.mod 文件指示 go build 工具去选取这个那个依赖并正常工作,那当然,我很高兴;但现在我想理解为什么连 linter 之前也报错,而现在一切都好了。我并不真的认为 VSCode 的 linter 会去检查 go mod 文件来看是否一切正常,所以我不太明白这个情况……
好吧,当一切正常运转时,一切就都好了,对吧?
这是一个典型的Go模块版本管理问题,主要原因是gopkg.in和GitHub仓库之间的版本映射不一致,以及Go模块系统与旧版GOPATH模式的冲突。
问题分析
从你的go env输出可以看到:
GO111MODULE=""- 这是空值,Go会根据项目位置自动选择模式GOPATH模式仍在生效- 你混合使用了
gopkg.in和github.com两种导入路径
解决方案
方案1:启用Go模块(推荐)
在你的项目根目录执行:
# 初始化Go模块
go mod init your-project-name
# 清理旧的包缓存
go clean -modcache
# 获取echo包
go get github.com/labstack/echo/v4
然后更新你的main.go,使用正确的导入路径:
package main
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
// 使用正确的中间件
e.Pre(middleware.RemoveTrailingSlash())
e.GET("/", func(c echo.Context) error {
return c.String(200, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}
方案2:使用正确的gopkg.in导入
如果你坚持使用gopkg.in,需要确保所有相关包都来自同一源:
package main
import (
"gopkg.in/labstack/echo.v4"
"gopkg.in/labstack/echo.v4/middleware"
)
func main() {
e := echo.New()
e.Pre(middleware.RemoveTrailingSlash())
e.GET("/", func(c echo.Context) error {
return c.String(200, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}
然后获取依赖:
go get gopkg.in/labstack/echo.v4
方案3:强制启用Go模块
设置环境变量强制使用模块模式:
export GO111MODULE=on
cd /your/project/path
go mod init
go get github.com/labstack/echo/v4
验证步骤
创建测试文件验证导入是否正常:
// test_import.go
package main
import (
"fmt"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
fmt.Printf("Echo version: %v\n", e)
}
运行测试:
go run test_import.go
关键点
- 不要混合使用
gopkg.in和github.com导入 - 选择一种并保持一致 - Go模块是未来 - 建议迁移到模块系统
- 版本后缀 -
v4表示主版本,在Go模块中必须体现在导入路径中
你的代码示例中类型不匹配错误正是因为同时导入了两个不同路径的echo包,Go编译器将它们视为完全不同的类型。



