Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go中的相对进口_Go - Fatal编程技术网

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

我有一个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()
}

但我总是得到未解决的引用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