Golang中的go get命令去哪了?v1.18版本解析

Golang中的go get命令去哪了?v1.18版本解析 我正在阅读 Mihalis Tsoukalos 所著的《精通 Go 语言(第二版)》。 我知道这本书是为 Go 1.12 版本编写的,之后关于 Go 模块的内容发生了变化,因此许多命令不再像以前那样工作。

我目前在第 6 章,在 ~/go/src/Mastering-Go-Second-Edition/ch06 目录下运行书中的示例(我的 bash 提示符:PS1='\W> ' 显示短目录名)。

ch06> go get github.com/mattn/go-sqlite3
go: go.mod file not found in current directory or any parent directory.
	'go get' is no longer supported outside a module.
	To build and install a command, use 'go install' with a version,
	like 'go install example.com/cmd@latest'
	For more information, see https://golang.org/doc/go-get-install-deprecation
	or run 'go help get' or 'go help install'.
ch06> go install github.com/mattn/go-sqlite3@latest
package github.com/mattn/go-sqlite3 is not a main package
ch06> mkdir /tmp/go-sqlite3
ch06> cd /tmp/go-sqlite3
go-sqlite3> go mod init go-sqlite3
go: creating new go.mod: module go-sqlite3
go-sqlite3> go get github.com/mattn/go-sqlite3
go: added github.com/mattn/go-sqlite3 v1.14.14
go-sqlite3> go get github.com/mattn/go-sqlite3@latest
go-sqlite3> find ~/go -type d -name go-sqlite3
/home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3
go-sqlite3> cd -
/home/marc/go/src/Mastering-Go-Second-Edition/ch06
ch06> go run htmlT.go
htmlT.go:6:2: no required module provides package github.com/mattn/go-sqlite3: go.mod file not found in current directory or any parent directory; see 'go help modules'
ch06> go build htmlT.go
htmlT.go:6:2: no required module provides package github.com/mattn/go-sqlite3: go.mod file not found in current directory or any parent directory; see 'go help modules'
ch06> ll -d $(find ~/go -type d -name go-sqlite3)
drwxrwxr-x 3 marc marc 4096 Jul 15 15:20 /home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3
ch06> ll $(find $(find ~/go -type d -name go-sqlite3) -type f)
-rw-rw-r-- 1 marc marc       9 Jul 15 15:20 /home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3/@v/list
-rw-rw-r-- 1 marc marc      52 Jul 15 15:20 /home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3/@v/v1.14.14.info
-rw-rw-r-- 1 marc marc       0 Jul 15 15:20 /home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3/@v/v1.14.14.lock
-rw-rw-r-- 1 marc marc      44 Jul 15 15:20 /home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3/@v/v1.14.14.mod
-rw------- 1 marc marc 2521345 Jul 15 15:20 /home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3/@v/v1.14.14.zip
-rw-rw-r-- 1 marc marc      47 Jul 15 15:20 /home/marc/go/pkg/mod/cache/download/github.com/mattn/go-sqlite3/@v/v1.14.14.ziphash

我原本期望时间戳显示的是今天的时间,而不是三天前的…… go-sqlite3 到底安装到哪里去了?

谢谢


更多关于Golang中的go get命令去哪了?v1.18版本解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

我相信是这样,但我必须承认我对Go语言确实很生疏。不过,是的,我想就是这样。

更多关于Golang中的go get命令去哪了?v1.18版本解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的——如果你在项目中引用了一个模块,go mod tidy 会自动添加它并为你执行 go get。根据文档

go mod tidy 确保 go.mod 文件与模块中的源代码匹配。它会添加构建当前模块包和依赖项所需的任何缺失模块要求,并移除那些不提供任何相关包的要求。它还会添加 go.sum 中缺失的条目并移除不必要的条目。

如你所见,它还会移除不再被引用的模块。我使用 VSCode,通常我只需在正在处理的 .go 文件中添加一个导入(例如 import "github.com/gorilla/mux"),然后 VSCode 就会知道我在 go.mod 中是否尚未引用它,我可以让它自动 go get 缺失的模块。

总之,我的评论只是以防你想完全按照书中所述使用 go get,并严格跟随书本操作。

go mod tidy 是否本可以替我执行 go get 呢? 或者只是发现它已经执行过了(在3天前)。 我认为我见证了 glot 模块一次隐式的 go get

ch08> go run CSVplot.go /tmp/doesnotexist
CSVplot.go:6:2: no required module provides package github.com/Arafatk/glot: go.mod file not found in current directory or any parent directory; see 'go help modules'
ch08> go mod init CSVplot
ch08> go mod tidy
...
go: finding module for package github.com/Arafatk/glot
...
go: downloading github.com/Arafatk/glot v0.0.0-20180312013246-79d5219000f0
...
go: found github.com/Arafatk/glot in github.com/Arafatk/glot v0.0.0-20180312013246-79d5219000f0
...

看起来你已经找到了解决方案。但我没在你的命令中看到 go get。为了能够使用 go get 获取依赖,你只需要初始化一个模块,然后就可以随心所欲地运行 go get 了:

# 初始化一个模块
$ go mod init test.com/repo
go: creating new go.mod: module test.com/repo

# 显示模块内容
$ cat go.mod
module test.com/repo

go 1.18

# 现在我们有了一个模块,可以像你正在读的书里那样运行 go get 了
$ go get github.com/mattn/go-sqlite3
go: downloading github.com/mattn/go-sqlite3 v1.14.14
go: added github.com/mattn/go-sqlite3 v1.14.14

# 模块现在需要 github.com/mattn/go-sqlite3
$ cat go.mod
module test.com/repo

go 1.18

require github.com/mattn/go-sqlite3 v1.14.14 // indirect

回答我自己的问题…

ch06> ll -d ~/go/pkg/mod/github.com/mattn/go-sqlite3@v1.14.14/
dr-xr-xr-x 4 marc marc 4096 Jul 15 15:20 /home/marc/go/pkg/mod/github.com/mattn/go-sqlite3@v1.14.14/
ch06> go mod init htmlT
go: creating new go.mod: module htmlT
go: to add module requirements and sums:
	go mod tidy
ch06> go mod tidy
go: finding module for package github.com/mactsouk/myModule/v2
go: finding module for package github.com/mattn/go-sqlite3
go: finding module for package github.com/mactsouk/myModule
go: found github.com/mattn/go-sqlite3 in github.com/mattn/go-sqlite3 v1.14.14
go: found github.com/mactsouk/myModule in github.com/mactsouk/myModule v1.1.0
go: found github.com/mactsouk/myModule/v2 in github.com/mactsouk/myModule/v2 v2.1.0

是这样吗?

在 Go 1.18 中,go get 的行为确实发生了变化。从 Go 1.16 开始,在模块外使用 go get 来安装可执行文件已被弃用,而 Go 1.18 进一步明确了这一变化。go get 现在主要用于在当前模块中添加、更新或移除依赖项,而不再用于安装可执行文件。

对于你的情况,问题在于你的项目目录 ~/go/src/Mastering-Go-Second-Edition/ch06 中没有 go.mod 文件。因此,Go 工具链无法识别这是一个模块,也无法管理依赖。

要解决这个问题,你需要在 ch06 目录中初始化一个 Go 模块,然后使用 go get 添加依赖。以下是具体步骤:

  1. 初始化模块: 在 ch06 目录中运行以下命令来创建 go.mod 文件:

    go mod init Mastering-Go-Second-Edition/ch06
    

    这将根据你的目录结构创建一个模块名称。

  2. 添加依赖: 使用 go get 添加 github.com/mattn/go-sqlite3 依赖:

    go get github.com/mattn/go-sqlite3
    

    这会在 go.mod 文件中添加依赖项,并下载该包到模块缓存中。

  3. 运行或构建程序: 之后,你可以正常使用 go rungo build

    go run htmlT.go
    

    go build htmlT.go
    

关于你提到的 go-sqlite3 安装位置的问题:当你之前在其他目录(如 /tmp/go-sqlite3)运行 go get 时,该依赖被下载到了 Go 模块缓存中(通常是 $GOPATH/pkg/mod),但这不是一个可执行文件的安装。对于库包(如 go-sqlite3),go get 只是将其下载到缓存中,供模块使用。可执行文件的安装现在应使用 go install,但仅适用于 main 包。

例如,如果你想安装一个命令行工具(如 golang.org/x/tools/cmd/goimports),你可以使用:

go install golang.org/x/tools/cmd/goimports@latest

总结:在你的项目目录中初始化模块是解决依赖问题的关键。go get 现在主要用于模块内的依赖管理,而不是全局安装包。

回到顶部