如何在go中导入本地包?


90

我是新手,正在研究要本地化的示例代码。

在原始的main.go导入语句中,它是:

 import (
    "log"
    "net/http"
    "github.com/foo/bar/myapp/common"
    "github.com/foo/bar/myapp/routers"
)

现在我已经commonrouters/home/me/go/src/myapp

所以我将import语句转换为:

import (
    "log"
    "net/http"
    "./common"
    "./routers"
)

但是当我运行时,go install myapp出现以下错误:

can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package

另外,当我在导入语句中使用commonandrouters代替./commonand./routers时,得到:

myapp/main.go:7:3: cannot find package "common" in any of:
    /usr/local/go/src/common (from $GOROOT)
    /home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
    /usr/local/go/src/routers (from $GOROOT)
    /home/me/go/src/routers (from $GOPATH)

我怎样才能解决这个问题?


5
无论导入路径如何,所有导入都是“本地”的。有关详细说明,请参见“如何编写Go代码”
JimB

21
@JimB抛开了哲学辩论,我所关心的是如何解决上述问题。
卡隆

3
我并不是要做出哲学上的声明,而是说所有导入都发生在本地文件系统中。无论它们是否来自远程仓库,都没有任何区别。不要尝试使用相对路径(有时可以使用,但不建议使用),而是阅读“如何编写Go代码”文档,尤其是“代码组织”部分
JimB

Answers:


63

好吧,我发现了问题所在。基本上,导入的开始路径是$HOME/go/src

因此,我只需要myapp在包名称前面添加,即导入应为:

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)

3
使用like这样的项目名称myapp是个坏主意,例如,如果更改项目名称,则所有导入都会失败
TomSawyer

7
有什么选择?Go不建议您使用相对导入。
山姆·霍姆斯

11
当然,如果更改项目名称,所有导入将失败。项目名称很少更改。
Damien Roche

21
好吧,从go1.11开始,您可以使用新的模块系统。go mod init <module_name>然后只是import "<module_name>/<pkg_name>"
尖叫

我们如何在我们的.go文件中导入github.com/dgrijalva/jwt-go?我的jwt-go文件夹位于src / github.com / dgrijalva
Manik Thakur

30

如果您使用的围棋1.5以上,你可以尝试使用vendoring功能。它允许您将本地包放在供应商文件夹下,并以较短的路径导入。在您的情况下,您可以将commonrouters文件夹放在vendor文件夹中,这样就可以

myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go

然后像这样导入

import (
    "common"
    "routers"
    "routers/middleware"
)

这将起作用,因为Go会尝试从项目的供应商目录(如果至少有一个.go文件)而不是$ GOPATH / src查找程序包。

仅供参考:您可以与供应商做更多的事情,因为此功能允许您将包的“所有依赖项代码”放在您自己项目的目录中,这样它就可以始终为所有构建获取相同的依赖项版本。就像python中的npm或pip一样,但是您需要手动将依赖项复制到您的项目中,或者如果您想使其变得简单,请尝试看一下Daniel Theophanes的文章

有关此功能的更多信息,请尝试在此处查找

Daniel Theophanes理解和使用供应商文件夹

Lucas Fernandes da Costa了解Go依赖管理

希望您或其他人有帮助


18

导入路径是相对于您$GOPATH$GOROOT环境变量的。例如,使用以下代码$GOPATH

GOPATH=/home/me/go

位于/home/me/go/src/lib/common/home/me/go/src/lib/routers中的软件包分别以以下方式导入:

import (
    "lib/common"
    "lib/routers"
)

是的,第一个例子是我的错误。
wlredeye '16

工具不支持的相对路径是什么意思?
wlredeye '16

2
您不能go install打包使用相对导入的文件。
JimB

我认为这是误会。我的意思是相对于GOPATH。不仅像“ ../../mypackage”之类的亲戚
wlredeye '16

那是参考您修复的相对于当前目录的导入部分。是的,所有用户导入都是相对于的$GOPATH/src
JimB

5

本地包是一个令人讨厌的问题。

对于我们公司中的某些项目,我们决定根本不使用子软件包。

  • $ glide install
  • $ go get
  • $ go install

所有的工作。

对于某些项目,我们使用子包,并使用完整路径导入本地包:

import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage

但是,如果我们分叉此项目,则子包仍然引用原始项目。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.