Go中的相对进口

时间:2016-07-22 03:16:52

标签: 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()
}

但我总是得到Unresolved reference test1。我是新来的。任何人都可以帮忙,为什么我收到这个错误?

5 个答案:

答案 0 :(得分:27)

Golang没有相对导入。
考虑到GOPATH,你应该使用abs路径:

GOPATH环境变量指定工作区的位置。它可能是您在开发Go代码时需要设置的唯一环境变量。首先,创建一个工作区目录并相应地设置GOPATH。见:https://golang.org/doc/code.html#GOPATH

导入路径:

导入路径是唯一标识包的字符串。包的导入路径对应于其在工作空间内或远程存储库中的位置(如下所述)。

标准库中的包具有简短的导入路径,例如" fmt"和" net / http"。对于您自己的软件包,您必须选择一个不太可能与未来添加到标准库或其他外部库的基础路径。

如果您将代码保存在某个源存储库中,那么您应该使用该源存储库的根作为基本路径。例如,如果您在github.com/user上有一个GitHub帐户,这应该是您的基本路径

请注意,在构建代码之前,您不需要将代码发布到远程存储库。组织代码只是一个好习惯,好像有一天你会发布它一样。实际上,您可以选择任意路径名称,只要它对标准库和更大的Go生态系统是唯一的。

示例:

此示例假定您已在OS环境中设置GOPATH=/goworkdir

档案:goworkdir/src/project1/utils/auth.go

package utils

func Test1() string {
    return "Test1"
}

档案:goworkdir/src/project1/controllers/login.go

package controllers

import "project1/utils"

func Test2() string {
    return utils.Test1()
}

档案:goworkdir/src/project1/main.go

package main

import (
    "fmt"
    "project1/controllers"
)

func main() {
    fmt.Println(controllers.Test2())
}

现在,如果您go run main.go,您应该看到输出:

Test1

答案 1 :(得分:15)

自从go 1.11开始引入go模块以来,现在有所不同。

因此,如果您切换到go模块,并且如果您的模块称为“ m”,则在项目树中进行相对导入的惯用方式将是使用:import "m/utils"import "m/controllers"在需要在项目中导入这些软件包的地方。 有关详细信息,请参见: https://github.com/golang/go/wiki/Modules#do-modules-work-with-relative-imports-like-import-subdir

答案 2 :(得分:4)

这是另一个示例项目结构,其中包含正确导入所需的文件内容:

test1/
   utils/
      texts.go
   main.go
   go.mod

具有以下内容:

go.mod

module mycompany.com/mytest

go 1.15

utils/texts.go(要使功能从其他程序包中可见,需要以大写字母开头):

package utils

func GetText() string {
  return "hello world"
}

main.go(仅支持完整的导入名称,没有更容易从同一模块导入的快捷方式):

package main

import (
  "fmt"
  "mycompany.com/test1/utils"
)

func main() {
  fmt.Println(GetText())
}

答案 3 :(得分:1)

鉴于此目录配置:

.
├── 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

所以你想做的事情有效。唯一的区别是我使用了大写的函数名,因为它需要导出符号。

答案 4 :(得分:0)

我认为您可以在源文件旁边创建一个供应商目录,该目录的作用类似于相对GOPATH,然后创建一个相对符号链接,链接到要在供应商目录中导入的包,然后导入包就好像供应商目录是$ GOPATH / src /.