我对go的新模块系统有一些问题,因为我想定义一个本地模块并将其导入主程序。本地软件包驻留在主软件包/根文件夹的文件夹中。想象一下下面的项目结构在$GOPATH
之外。
项目结构
./main.go
package main
import "fmt"
import "example.com/localModule/model"
func main() {
var p = model.Person{name: "Dieter", age:25}
fmt.Printf("Hello %s\n", p.name)
}
./model/person.go
package model
type Person struct {
name string
age int
}
在根文件夹中,我通过调用
go mod init example.com/localModule
在model/
文件夹中,我调用
go mod init example.com/localModule/model
错误
在根文件夹中调用以下命令失败。
$ go get
go build example.com/localModule/model: no Go files in
$ go build
main.go:4:8: unknown import path "example.com/localModule/model": cannot find module providing package example.com/localModule/model
go get的错误消息被切断了,我没有解析错。
我不打算将模块推到服务器上,只是需要一种引用本地包model
的方法,所以我分别选择了example.com/localModule/
和example.com/localModule/model
。
我在运行MacOS 10.13.6的MacBook上使用go1.11 darwin/amd64
。
3条答案
按热度按时间bf1o4zei1#
您可以通过在go. mod中添加一个require语句和一个匹配的replace语句以及一个相对文件路径来获得本地“子”模块。
eulz3vhy2#
根问题
您得到此错误的原因是因为您定义了两个模块,它们不知道如何在本地磁盘上找到对方。
方案一:
replace
您可以将
replace
指令添加到顶层模块的go.mod
文件中,例如:replace example.com/localModule/model v0.0.0 => ./model
这使得顶部模块可以找到磁盘上的其他模块。在Modules wiki上的replace FAQ和“多模块库”部分有更详细的介绍。
然而,这是一个更复杂的解决方案,可能很难得到正确的,通常是更多的正在进行的工作,并有一些限制,如
replace
被忽略的所有模块,除了当前模块。对于大多数人来说,多模块的repo可能不是他们想要的。在这一点上,真正需要在单个存储库中包含多个模块的情况相对较少。方案二:一个repo ==一个模块
虽然可以使用
replace
指令,但更常见和直接的解决方案是:go.mod
文件,go.mod
文件放在存储库的根目录下。这是一个非常简单的解决方案,这意味着存储库中的两个包将能够自动找到对方,而不需要任何
replace
,这避免了您报告的错误消息。replace
多模块存储库,与单模块存储库?Russ考克斯在#26664中评论道:
对于除高级用户之外的所有用户,您可能希望采用一个repo =一个模块的惯例。对于代码存储选项的长期发展来说,一个repo * 可以 * 包含多个模块是很重要的,但几乎可以肯定的是,默认情况下你不想这样做。
如果你想在一个仓库中定义多个模块,那么关于如何正确地做到这一点有相当多的细微差别,并且应该阅读Modules wiki的整个部分,了解如何管理与单个仓库中的多个模块相关的复杂性,包括以下建议:
添加模块、删除模块以及在单个存储库 * 中使用多个模块对模块进行版本控制需要相当的谨慎和考虑,因此管理单个模块存储库 * 比管理现有存储库中的多个模块几乎总是更容易和更简单。
f4t66c6m3#
对我来说,下面的命令工作
创建go.mod
go mod init "github.com/udacity/ud615/app/health"
然后将其他模块下载为
go mod tidy