如何访问Go语言中的嵌套模块(子模块)?

q7solyqu  于 2023-02-06  发布在  Go
关注(0)|答案(3)|浏览(375)

Go版本:1.12.9
下面是一个简单的演示项目的结构:

因此,我们有一个模块domain,它包含两个模块:活动人员
我想在主文件=〉modules.go 中使用所有嵌套模块的域。
我知道如何在主 go.mod 中导入 domain

module modules

go 1.12

replace modules/domain v0.0.0 => ./domain

require modules/domain v0.0.0

所以在那之后可以使用 domain/domain.go 的代码,但是我不能访问 activityperson 模块的代码。
是的,我可以手动导入嵌套模块,例如:
(main进入模式):

module modules

go 1.12

replace modules/domain v0.0.0 => ./domain

replace modules/domain/activity v0.0.0 => ./domain/activity

require (
    modules/domain v0.0.0
    modules/domain/activity v0.0.0
)

但我不想手动导入所有子模块。
如何配置模块导入domain及其所有子模块?

mrzz3bfm

mrzz3bfm1#

是的,我可以手动导入嵌套模块[...],但我不想手动导入所有子模块。如何配置模块以导入包含所有子模块的域?
你不能这么做。
一些背景:

  • 没有真正的"子"模块概念,所有模块都是平等的。
  • Package 相同:所有(*)包都是相同的。如果要使用某个包,则必须导入它。
  • 文件系统中的布局并不意味着包之间有任何技术上的联系(例如net/http/cookiejar与net/http的关系就像与crypto/md5的关系一样:完全不是)。
  • 成为模块的一部分并没有多大意义:模块只是一组版本化在一起的包,并没有在这些包之间添加任何额外的关系。

规则非常简单:如果你想导入一个包,你必须先导入它。
事实上,没有神奇的通配符导入可能看起来很烦人(见下文),但可以防止意外导入:添加一个包并不会神奇地导入它(并执行它的init函数!)
在现实生活中,导入所有的包并不是那么烦人,因为"正常的" Go语言代码不会使用小包,这对于那些被灌输了Java/C #/PHP/Node "项目架构"的人来说是一个常见的错误,因为他们有很多文件夹和小类。在围棋中不要这样做,这是没有帮助的,甚至经常导致循环导入,伤害。
模块也是一样。Go语言的模块可能不是你所想的那样。模块是一组包,它们被版本化在一起。我怀疑是否有理由同时为包的个人和域提供不同的版本。(在一个仓库/项目中有几个模块是允许的,但是有一个以上的模块是非常罕见的,你的显然不是)。
最佳建议(按相关性排序):

  • 不要让每个包都有自己的模块。
  • 别再做小包裹了。
  • 不要试图模仿其他语言中可能用到的源代码布局("体系结构")。

(*)内部和供应商软件包是例外,不适用于您的问题。

7gs2gvoe

7gs2gvoe2#

go 1.18通过go.work文件支持新的multi-workspace特性.欲了解更多信息,请查看golang workspace proposal

nfs0ujit

nfs0ujit3#

我在《Go语言1.20》中遇到过类似的情况,下面是我的解决方法。

Package

我在Go语言项目中使用了一个仓库作为包,这个仓库使用了一个子模块。
下面是我的仓库my-repository/services中的. gitmodules文件:

变更

我错过了什么:
在引入工作区之后,子模块被区别对待。所以现在我需要创建一个go.work文件。需要和go.mod放在同一层。

  • 去工作吧 *
go 1.20

use ./validator/validate

用法

现在我想在我的主存储库中使用这个包。将它导入为,

这解决了我的问题。您可以在以下位置找到文档:Setting up your workspace

相关问题