Go 如何解决本地模块的可传递依赖关系

Go 如何解决本地模块的可传递依赖关系,go,go-modules,Go,Go Modules,在一些随机文件夹中,有3个文件夹a、b、c。每个文件夹都包含一个mod文件 mod文件包含以下内容 go.mod在一个 module a go 1.13 进入b区 module b go 1.13 require a v0.0.0 replace a v0.0.0 => ./../a go.mod在c中 module c go 1.13 require b v0.0.0 replace b v0.0.0 => ./../b 模块b不会抛出错误。但是模块c抛出错误 go: b@

在一些随机文件夹中,有3个文件夹a、b、c。每个文件夹都包含一个mod文件

mod文件包含以下内容

go.mod在一个

module a

go 1.13
进入b区

module b
go 1.13
require a v0.0.0
replace a v0.0.0 => ./../a
go.mod在c中

module c
go 1.13
require b v0.0.0
replace b v0.0.0 => ./../b
模块b不会抛出错误。但是模块c抛出错误

go: b@v0.0.0 requires
a@v0.0.0: unrecognized import path "a" (import path does not begin with hostname)
每个模块的模块名中必须有一个点(.)

“一些随机文件夹”更改到example.com。现在example.com命名文件夹包含所有a.b.c文件夹。下面是模块现在的外观

模块A看起来像

module example.com/a
go 1.13
模块B看起来像

module example.com/b
go 1.13
require example.com/a v0.0.0
replace example.com/a v0.0.0 => ../a
module example.com/c
go 1.13
require example.com/b v0.0.0
replace example.com/b v0.0.0 => ../b
模块C看起来像

module example.com/b
go 1.13
require example.com/a v0.0.0
replace example.com/a v0.0.0 => ../a
module example.com/c
go 1.13
require example.com/b v0.0.0
replace example.com/b v0.0.0 => ../b
太糟糕了!错误

go: example.com/b@v0.0.0 requires
example.com/a@v0.0.0: unrecognized import path "example.com/a" (https fetch: Get 
https://example.com/a?go-get=1: dial tcp 208.73.210.202:443: connect: connection refused)
本地模块的可传递依赖关系是如何工作的? 为什么要点击example.com带来模块? 发生了什么事?

exclude
replace
指令仅在当前(“主”)模块上运行
exclude
replace
指令在构建主模块时会被忽略。
因此,
replace
exclude
语句允许主模块完全控制自己的构建,不受依赖关系的完全控制。(有关何时使用
replace
指令的讨论,请参阅常见问题解答)

而且在

主模块的go.mod文件通过require、replace和exclude语句定义了可供go命令使用的精确包集。通过以下require语句找到的依赖模块也有助于该包集的定义,但仅通过其go.mod文件的require语句:忽略依赖模块中的任何replace和exclude语句。因此,replace和exclude语句允许主模块完全控制自己的构建,而不受依赖项的完全控制

构建模块
c
时找不到包
a
,因此
go
工具尝试解析它,尝试下载它。这就是为什么它试图将包名解释为应该以主机名开头的名称

您不需要将包
a
重命名为
example.com/a
,但必须将
replace
指令添加到
c
go.mod
中,告诉包
a
的位置。

exclude
replace
指令仅在当前(“主”)模块上运行
exclude
replace
指令在构建主模块时会被忽略。
因此,
replace
exclude
语句允许主模块完全控制自己的构建,不受依赖关系的完全控制。(有关何时使用
replace
指令的讨论,请参阅常见问题解答)

而且在

主模块的go.mod文件通过require、replace和exclude语句定义了可供go命令使用的精确包集。通过以下require语句找到的依赖模块也有助于该包集的定义,但仅通过其go.mod文件的require语句:忽略依赖模块中的任何replace和exclude语句。因此,replace和exclude语句允许主模块完全控制自己的构建,而不受依赖项的完全控制

构建模块
c
时找不到包
a
,因此
go
工具尝试解析它,尝试下载它。这就是为什么它试图将包名解释为应该以主机名开头的名称


您不需要将程序包
a
重命名为
example.com/a
,但必须将
replace
指令添加到
c
go.mod
中,告诉程序包
a
的位置。

感谢您的解决方案……但这是否可行?我认为导入的整个想法是,作为一名开发人员,我将从我导入的模块的所有依赖项中抽象出来。假设我有一个大项目,其中有10-12个层次结构,我想使用最新的。我必须包含每个导入库的依赖项@deepg仅当您使用的模块具有
replace
指令时才需要此命令,否则这些指令应仅用于测试/本地开发。发布模块时,它不应依赖于不属于该模块的本地包。使用这些模块您无需做任何事情:您只需导入它们,然后
go
工具和模块系统会自动解析所有依赖项。感谢@icza的详细解释。这真的很有帮助。老实说。Go从发展角度带来了非常新的视角。然而,文件没有突出它的细微差别。别误会,这些行中隐藏着大量的信息,但它就像海洋中的一颗明珠。@deepg有很多内容需要涵盖,因此一个单页、少页的文档不可能涵盖任何人需要的所有内容。官方主页始终是一个很好的起点,它也涵盖了这一点(添加为第二引语)。Stackoverflow也是一个很好的询问您无法找到或理解的内容的地方。感谢您提供的解决方案……但这是否可行?我认为导入的整个想法是,作为一名开发人员,我将从我导入的模块的所有依赖项中抽象出来。假设我有一个大项目,其中有10-12个层次结构,我想使用最新的。我必须包含每个导入库的依赖项@deepg仅当您使用的模块具有
replace
指令时才需要此命令,否则这些指令应仅用于测试/本地开发。什么时候