在学习过程中,我正在玩自己的图书馆。这是我做的:在我的$ GOPATH / src中我有两个文件夹:mylibs
和test
。 test
文件夹中有一个名为test.go
的文件,其中包含
package test
import "mylibs/hi/saysHi"
func main() {
saysHi.SayHi()
}
mylibs
文件夹包含另一个名为hi
的文件夹,其中包含一个名为saysHi.go
的文件,其中包含:
package saysHi
import "fmt"
func SayHi() {
fmt.Printf("Hi\n")
}
所以目录结构如下所示:
问题在于,当我尝试编译test
时,它抱怨说
cannot find package "mylibs/hi/saysHi" in any of:
[...]
$GOPATH/src/mylibs/hi/saysHi (from $GOPATH)
我故意使目录结构比必要更深。如果我创建一个更简单的目录结构,我将saysHi.go
放在$GOPATH/saysHi/saysHi.go
中,那么它就可以了。
但我不明白为什么这不起作用的原因。有什么想法吗?
答案 0 :(得分:3)
一般来说,您的目录名称应与包名称匹配。所以,如果你定义
package saysHi
并希望用
导入它 import "mylibs/hi/saysHi"
你应该把它放在这样的结构中:
包中的.go
文件的名称与导入路径没有区别,因此您可以随意调用.go
文件。
为了进一步解释,您使用的导入路径应该是包含该包的目录的名称。但是,如果在该目录中定义了不同的包名称,则应使用该名称来访问代码中的包。这可能会造成混淆,因此最好避免它,直到您了解它的最佳使用位置(提示:包版本控制)。
这会让人感到困惑,例如,如果你的包裹在路径中
在saysHi.go
内定义,
package saysHi
然后在test.go中,您将使用
导入它import "mylibs/hi"
并与
一起使用saysHi.SayHi()
请注意如何使用最终目录hi
导入它,但使用名称为saysHi
的目录。
万一你不知道以下内容:你的测试文件被称为test.go
,这很好,如果它只是一个例子,而不是一个实际的saysHi.go
的测试文件。但如果它是包含saysHi.go
测试的文件,则接受的Go标准是将文件命名为saysHi_test.go
并将其放在saysHi.go
旁边的同一个包中。
我提到了如何允许您从目录名称中选择不同的包名称。但实际上有一种方法可以编写代码,以免混淆:
import (
saysHi "mylibs/hi"
)
会从mylibs/hi
目录中导入它,并记下它应与saysHi
一起使用的事实,因此您的代码读者可以理解,无需查看{{ 1}}代码。