如何从父目录进行相对导入?
来自meme/cmd/meme
:
import "../../../meme"
这会产生一个模棱两可的错误:
matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ go get bitbucket.org/anacrolix/meme/cmd/meme
can't load package: /home/matt/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme/main.go:8:2: local import "../../../meme" in non-local package
matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH
/home/matt/gopath
如何从父目录导入本地?
答案 0 :(得分:48)
编辑:相对导入路径不是Go的方式。缺乏文档显示了相对路径的流行程度,我没有看到使用它们的原因。 Go的推荐代码组织运行良好。每个包都应具有唯一的导入路径,并使用相同的导入路径到处进行导入。
查看github.com/ha/doozerd/peer
imports its neighbors之类的广告资源。这是Go项目中的常见做法,我已经看过很多次了。包camlistore.org/pkg/auth
(也在GitHub上;由Go的主要作者之一撰写)以完整路径导入camlistore.org/pkg/netutil
。
即使您在同一个项目中同时拥有命令和库,这种方法也可行。在您的原始问题中,您明智地要求最佳实践。我尽力解释这方面的最佳实践。
Go中的导入路径不能相对。我建议阅读How to Write Go Code,这是组织Go项目的基本读物。这是一个简短的概述:
为您的Go开发创建一个类似~/go
的目录。然后说:
$ export GOPATH=~/go
$ mkdir $GOPATH/{src,bin,pkg}
$GOPATH/src
包含所有Go包的源代码,甚至是您使用go get
下载的源代码。 bin
和pkg
会保留编辑内容。程序包名称为main
的程序包是命令,并且会生成到$GOPATH/bin
的可执行二进制文件。其他包是库,它们的编译目标文件放在$GOPATH/pkg
。
现在,如果您将代码放在$GOPATH/src/matt/meme
中,则可以按import "matt/meme"
导入代码。建议为包名使用前缀,并为标准库保留短包名。这就是为什么我使用$GOPATH/src/matt/meme
代替$GOPATH/src/meme
。
围绕这个想法组织你的代码。
答案 1 :(得分:17)
感谢您添加问题。首先,答案,然后一些解释。我按照
构建了你的代码main.go
中的导入行设置回“../../../meme”,如您所愿。go run main.go
或go build main.go
工作。我之前在评论安装工作时的评论错了;我应该说去构建。
然而,关键是go build
单独不起作用;你必须输入go build main.go
。这是因为go命令不允许“在非本地包中进行本地导入”。你是对的,规格在这里没什么帮助。它狡猾地说:“ImportPath的解释依赖于实现。”当前的实现行为是使用CL 5787055设置的,随后是debated at length的Go-nuts。
“Local”表示使用文件系统相对路径表示。显然,以..开头的相对路径是本地的,所以诀窍就是让go
命令将main视为本地包。键入go build
时显然不会这样做,但键入go build main.go
时会这样做。
答案 2 :(得分:3)
直接手动使用编译器,链接器,...支持Relarive导入。 'go'(构建)工具不支持相同(以某种方式与Java相比)。
答案 3 :(得分:0)
这可能无法回答原始问题,但是我在不需要时尝试执行上述操作,我要做的就是用go.mod
临时更新replace
: / p>
module github.com/pselle/foo
replace github.com/pselle/bar => /Users/pselle/Projects/bar
require (
github.com/pselle/bar v1.0.0
)
参考: https://thewebivore.com/using-replace-in-go-mod-to-point-to-your-local-module/