假设我有一个包文件夹,如下所示:
hello
|---main.go
|---utilities.go
在 main.go
中,我有:
package main
在 utilities.go
中,我有:
package hello
我这样做是因为:
-
我不想将所有实用程序放入单个
main.go
文件中 . -
实用程序仅由此程序包使用,因此我不想将其从
hello
文件夹中删除 .
但是当我运行 go list hello
时,它给了我这个:
无法加载包:包hello:在E:\ Workbench \ Go \ src \ hello中找到包main(main.go)和hello(utilities.go)
然后我删除 utilities.go
并再次尝试 go list hello
只有 main.go
. 它给了我这个:
你好
那么我必须将所有实用程序移动到另一个包文件夹吗?
我是否必须在hello包文件夹中仅保留单个 main.go
,因为它似乎与其他包名称不相容?
ADD 1
一个有用的参考:http://thenewstack.io/understanding-golang-packages/
ADD 2
经过几个简短的实验,我猜 import yyy
决定链接搜索路径,而 package xxx
声明决定编译的 .a
文件中的导出符号名称 .
因为我注意到了这些事实:
-
package xxx
声明不必与包含的包文件夹名称相同,例如yyy
. -
但是
import yyy
声明必须使用包文件夹路径yyy
. -
使用包中的符号时,我们仍然必须使用
xxx.Symbol
而不是yyy.Symbol
.
ADD 3
为了证实我在ADD 2中的猜测,我这样做了:
(以pkg1 \ file1.go)
package pkg2 // I deliberately use a different pkg name "pkg2" rather than the folder name "pkg1"
import "fmt"
func FA() {
fmt.Println("in the pkg2.FA")
}
(CMD1 \ main.go)
package main
import "pkg1"
func main() {
pkg2.FA() //here, the FA is referenced via "pkg2" rather than the "pkg1".
}
以上2个文件可以编译运行 .
但如果我改为:
(CMD1 \ main.go)
package main
import "pkg1"
func main() {
pkg1.FA() //here, the FA is referenced via "pkg1" as in the import statement. Should work, isn't it?
}
这将给出:
.... \ src \ cmd1 \ main.go:3:导入但未使用:“pkg1”为pkg2 .... \ src \ cmd1 \ main.go:6:undefined:pkg1 in pkg1.FA
为了双重确认,我用 go tool nm pkg1.a
, I didn't see package name affects the exported symbols 检查了编译的 pkg1.a
文件 . (顺便说一下,GNU nm工具似乎无法识别golang .a
文件格式 . )
U
515 T %22%22.FA <========== this is my fuction FA
67b R %22%22.FA·f <========== this is my fuction FA
5eb T %22%22.init
67b B %22%22.initdone·
683 R %22%22.init·f
U fmt.Println
U fmt.init
673 R gclocals·33cdeccccebe80329f1fdbee7f5874cb
66b R gclocals·69c1753bd5f81501d95132d08af04464
65b R gclocals·e29b39dba2f7b47ee8f21f123fdd2633
64d R go.string."in the pkg2.FA"
63d R go.string.hdr."in the pkg2.FA"
7d2 R go.typelink.*[1]interface {}
796 R go.typelink.[1]interface {}
737 R go.typelink.[]interface {}
U runtime.algarray
U runtime.convT2E
6ec R runtime.gcbits.01
68b R runtime.gcbits.03
U runtime.morestack_noctxt
U runtime.throwinit
79a R type.*[1]interface {}
7d6 R type..importpath.fmt.
73b R type..namedata.*[1]interface {}.
6ed R type..namedata.*[]interface {}.
68c R type..namedata.*interface {}.
74e R type.[1]interface {}
6ff R type.[]interface {}
69c R type.interface {}
U type.string
所以到目前为止的结论是:
当声明的包名称是包文件夹名称中的 different 时,包声明将用作包的备用名称 .
相当于此,但隐含地:
import pkg2 "pkg1"
顺便说一句,因为包声明没有反映在已编译的 .a
文件中,我想golang编译需要存在 .go
文件 .
1 回答
go文件在同一个包中AKA文件夹必须具有相同的包名 . 唯一的例外是可以具有_test扩展的测试 . 规则是1个文件夹,1个包因此同一个文件夹中所有go文件的包名称相同 .
答案是肯定的,将“hello”包文件移动到它们自己的文件夹中,或者对同一目录中的所有文件使用相同的包名 .