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() } 但是我总是得到未解析的引用
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
package utils
func Test1() string {
return "Test1"
}
package controllers
import "project1/utils"
func Test2() string {
return utils.Test1()
}
package main
import (
"fmt"
"project1/controllers"
)
func main() {
fmt.Println(controllers.Test2())
}
文件:goworkdir/src/project1/controllers/login.go
package utils
func Test1() string {
return "Test1"
}
package controllers
import "project1/utils"
func Test2() string {
return utils.Test1()
}
package main
import (
"fmt"
"project1/controllers"
)
func main() {
fmt.Println(controllers.Test2())
}
文件:goworkdir/src/project1/main.go
package utils
func Test1() string {
return "Test1"
}
package controllers
import "project1/utils"
func Test2() string {
return utils.Test1()
}
package main
import (
"fmt"
"project1/controllers"
)
func main() {
fmt.Println(controllers.Test2())
}
现在,如果您go运行main.go
,您应该会看到输出:
Test1
我认为您可以在源文件旁边放置一个供应商目录,其作用类似于相对GOPATH,然后创建一个相对符号链接,该链接指向您要在供应商目录中导入的包,然后导入包,就好像供应商目录是您的$GOPATH/src/这与go 1.11引入go模块后有所不同 因此,如果您切换到go模块,并且您的模块名为“m”,那么在项目树中进行相对导入的惯用方法是:在需要导入项目中这些包的位置使用:
import“m/utils”
和import“m/controllers”
。
有关详细信息,请参阅:
GoLand用户-默认情况下,这些形式的导入在IDE中显示为错误。您需要在设置中启用Go模块集成
以下是另一个示例项目结构,其中包含正确导入所需的文件内容:
test1/
utils/
texts.go
main.go
go.mod
包括以下内容:
go.mod
:
module mycompany.com/mytest
go 1.15
utils/text.go
(要使函数从不同的包中可见,它需要以大写字母开头):
main.go
(只支持完整的导入名称,没有从同一模块导入的快捷方式):
给定此目录配置:
.
├── 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符号表示相对”,那么是的,您是对的。从这个意义上讲,这可能不符合“relative”的定义。relative的意思是不依赖外部名称或配置,例如“m”-这完全是基于相对目录结构而不是其他的。从这个意义上说,这不是相对的。它将是
“mycompany.com/mytest/test1/utils”
而不是“mycompany.com/test1/utils”
,其余一切都是完美的。