英文:
Why there are two "require" blocks in go.mod since Go 1.17?
问题
我已经创建了一个小的Go应用程序。几天前,我从Go 1.15升级到了1.17,并且还使用go get -u
升级了包。在这些更改之后,我的go.mod文件中有2个require块。这是为什么?它是什么意思?这样做是否正常?应用程序仍然可以正确构建。
go.mod文件内容如下:
module github.com/jozo/simple-pomodoro
go 1.17
require (
fyne.io/fyne/v2 v2.1.0
github.com/dsnet/golib/memfile v1.0.0
github.com/faiface/beep v1.1.0
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259 // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be // indirect
github.com/godbus/dbus/v5 v5.0.5 // indirect
github.com/hajimehoshi/oto v1.0.1 // indirect
github.com/srwiley/oksvg v0.0.0-20210519022825-9fc0c575d5fe // indirect
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect
github.com/yuin/goldmark v1.4.1 // indirect
golang.org/x/exp v0.0.0-20210916165020-5cb4fee858ee // indirect
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 // indirect
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 // indirect
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
)
英文:
I've created a small go application. Few days back I've upgraded from go 1.15 to 1.17 and I've also upgraded packages with go get -u
. After the changes I have 2 require blocks in my go.mod file. Why is it? What does it mean? Is it ok or something is broken?
Application still builds correctly.
go.mod file:
module github.com/jozo/simple-pomodoro
go 1.17
require (
fyne.io/fyne/v2 v2.1.0
github.com/dsnet/golib/memfile v1.0.0
github.com/faiface/beep v1.1.0
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259 // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be // indirect
github.com/godbus/dbus/v5 v5.0.5 // indirect
github.com/hajimehoshi/oto v1.0.1 // indirect
github.com/srwiley/oksvg v0.0.0-20210519022825-9fc0c575d5fe // indirect
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect
github.com/yuin/goldmark v1.4.1 // indirect
golang.org/x/exp v0.0.0-20210916165020-5cb4fee858ee // indirect
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 // indirect
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 // indirect
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
)
答案1
得分: 45
因为在Go 1.17中,模块图已经被更改以实现修剪和延迟加载。第二个require
块包含间接依赖项。
https://golang.org/doc/go1.17#go-command
> 如果一个模块指定了go 1.17或更高版本,模块图仅包括其他go 1.17模块的直接依赖项,而不包括它们的全部传递依赖项。[...]
> [...] 如果一个模块在其go.mod文件中指定了go 1.17或更高版本,它的go.mod文件现在包含对每个提供传递导入包的模块的显式require指令。 (在以前的版本中,go.mod文件通常只包含对直接导入包的显式要求。)
> 由于在扩展的Go 1.17 go.mod文件中显式要求的数量可能会大大增加,因此go 1.17模块中对间接依赖项的新添加要求在与包含直接依赖项的块不同的require块中维护。
注意:您在问题中发布的go.mod
文件在第一个require块中有//indirect
依赖项。根据引用文档中的“新添加”一词,我怀疑这是因为那些//indirect
依赖项已经在那里列出,并且go mod tidy
不会重新排列它们。如果您:
- 手动删除其中一个
- 和/或重新创建具有设置为
1.17
或更高版本的Go版本的go.mod
文件 - 和/或运行
go mod tidy -go=1.17
那么它将在两个块中分离直接和//indirect
依赖项。无论如何,这只是一个视觉上的便利,文档并没有强制创建两个单独的块。
<hr>
其他参考资料:
-
图修剪:https://go.dev/ref/mod#graph-pruning
-
依赖于
go.mod
的go
指令的行为:https://go.dev/ref/mod#go-mod-file-go
英文:
Because in Go 1.17 the module graph has been changed to enable pruning and lazy loading. The second require
block contains indirect dependencies.
https://golang.org/doc/go1.17#go-command
> If a module specifies go 1.17 or higher, the module graph includes only the immediate dependencies of other go 1.17 modules, not their full transitive dependencies. [...]
> [...] If a module specifies go 1.17 or higher in its go.mod file, its go.mod file now contains an explicit require directive for every module that provides a transitively-imported package. (In previous versions, the go.mod file typically only included explicit requirements for directly-imported packages.)
> Because the number of explicit requirements may be substantially larger in an expanded Go 1.17 go.mod file, the newly-added requirements on indirect dependencies in a go 1.17 module are maintained in a separate require block from the block containing direct dependencies.
Note: the go.mod
file that you posted in your question has //indirect
dependencies in the first require block. I suspect, based on the wording "newly-added" in the quoted docs, that this is because those //indirect
dependencies were already listed there and go mod tidy
doesn't rearrange them. If you:
- manually delete one of those
- and/or recreate the
go.mod
file with Go version set to1.17
or higher - and/or run
go mod tidy -go=1.17
then it will separate direct and //indirect
dependencies in the two blocks. Anyway, this is a visual convenience, the documentation doesn't mandate creation of two separate blocks.
<hr>
Additional references:
-
graph pruning: https://go.dev/ref/mod#graph-pruning
-
behaviors dependent on
go.mod
'sgo
directive: https://go.dev/ref/mod#go-mod-file-go
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论