Go中的相对进口
我有一个go项目,目录结构如下Go中的相对进口,go,Go,我有一个go项目,目录结构如下 utils(pkg) | auth.go (has a function names test1) controllers(pkg) | login.go (has a function names test2) 我正在尝试从login.go访问函数test1。这就是我所做的 import "../utils" func test2(c *gin.Context) bool{ utils.test1() } 但我总是得到未解决的引用t
utils(pkg)
| auth.go (has a function names test1)
controllers(pkg)
| login.go (has a function names test2)
我正在尝试从login.go访问函数test1。这就是我所做的
import "../utils"
func test2(c *gin.Context) bool{
utils.test1()
}
但我总是得到未解决的引用test1。我是新来的。有人能帮我解释为什么我会出现这个错误吗?不,Go中没有相对导入。 您应该使用绝对路径: GOPATH环境变量指定工作区的位置。它可能是开发Go代码时需要设置的唯一环境变量。要开始,请创建一个工作区目录并相应地设置GOPATH。见: 导入路径 导入路径是唯一标识包的字符串。包的导入路径对应于其在工作区中的位置 或者在下面解释的远程存储库中 标准库中的包具有较短的导入路径 例如fmt和net/http。对于您自己的软件包,您必须选择 基本路径不太可能与未来添加到 标准库或其他外部库 如果将代码保存在某个源存储库中,那么应该使用该源存储库的根作为基本路径。对于 例如,如果您在GitHub.com/user上有一个GitHub帐户,那么 这是你的基本路线 请注意,您不需要将代码发布到远程存储库 在你建造它之前。组织代码只是一个好习惯 好像有一天你会出版它。实际上,你可以选择任何一种 任意路径名,只要它对标准库是唯一的 以及更大的围棋生态系统 例如: 本例假设您在操作系统环境中设置了GOPATH=/goworkdir 文件:goworkdir/src/project1/utils/auth.go 文件:goworkdir/src/project1/controllers/login.go 文件:goworkdir/src/project1/main.go 现在,如果运行main.go,您应该会看到输出:
Test1
我认为您可以在源文件旁边放置一个供应商目录,其作用类似于相对GOPATH,然后创建一个相对符号链接,该链接指向您要在供应商目录中导入的包,然后导入包,就好像供应商目录是您的$GOPATH/src/这与go 1.11引入go模块后有所不同 因此,如果您切换到go模块,并且您的模块名为m,那么在项目树中进行相对导入的惯用方法是:在需要在项目中导入这些包的位置导入m/UTIL和导入m/Controller。 有关详细信息,请参阅: GoLand用户-默认情况下,这些形式的导入在IDE中显示为错误。您需要在设置中启用Go模块集成
以下是另一个示例项目结构,其中包含正确导入所需的文件内容:
test1/
utils/
texts.go
main.go
go.mod
包括以下内容:
go.mod:
utils/text.go要使函数从其他包可见,它需要以大写字母开头:
package utils
func GetText() string {
return "hello world"
}
main.go仅支持完整的导入名称,没有从同一模块导入的快捷方式:
package main
import (
"fmt"
"mycompany.com/test1/utils"
)
func main() {
fmt.Println(GetText())
}
给定此目录配置:
.
├── controllers
│ └── login.go
├── main.go
└── utils
└── auth.go
文件main.go:
package main
import "./controllers"
func main() {
controllers.Test2("Hello")
}
文件控制器/login.go:
package controllers
import "../utils"
func Test2(msg string) {
utils.Test1(msg)
}
文件utils/auth.go:
package utils
import . "fmt"
func Test1(msg string) {
Println(msg)
}
成果工程:
$ go build -o program main.go
$ ./program
Hello
所以你想做的事很管用。唯一的区别是我使用了大写函数名,因为导出符号是必需的。你的意思是,如果我更改保存代码的存储库,那么我需要修改代码中的所有导入语句?这似乎不对。这个答案只是部分正确。如果使用GOPATH,那么实际的导入语句将采用以下形式:import github.com/user/project1/utils这是因为go install与git存储库一起工作。按照答案中的建议,可以使用基于相对文件系统的路径,但是,这只能在本地工作,并且项目将无法与其他人共享。首先,感谢您指出此重要更新!一个小细节:在项目树中进行相对导入的惯用方法是[…]——您描述的仍然是绝对导入,而不是相对导入。事实上,根据您链接到的常见问题中提到的GitHub问题,相对导入以前是可能的,但现在显然不再是了。我想这取决于如何定义绝对和相对。我的意思是相对的,在某种意义上,它只存在于你当前的项目中。仅相对于当前项目模块名称存在。不在任何公开的Git回购中;不在系统的中央模块存储器中。在当前文件系统、代码库之外不可见。如果您的意思是相对的,就像在文件系统中使用.././like符号表示的相对,那么是的,您是对的。在这个词的意义上,这可能不符合相对的定义。相对的意思是不依赖外部名称或配置(如m),这完全是基于相对目录结构而不是其他。在 从某种意义上说,这不是相对的。它应该是mycompany.com/mytest/test1/utils而不是mycompany.com/test1/utils,其余一切都是完美的。
package main
import "./controllers"
func main() {
controllers.Test2("Hello")
}
package controllers
import "../utils"
func Test2(msg string) {
utils.Test1(msg)
}
package utils
import . "fmt"
func Test1(msg string) {
Println(msg)
}
$ go build -o program main.go
$ ./program
Hello