假设我有一个包文件夹,如下所示:
1 2 3 | hello |---main.go |---utilities.go |
在
1 | package main |
在
1 | package hello |
我这样做是因为:
-
我不想将所有实用程序放入单个
main.go 文件中。 -
并且实用程序仅由此程序包使用,因此我不想将其从
hello 文件夹中删除。
但是当我运行
can't load package: package hello: found packages main (main.go) and
hello (utilities.go) in E:\Workbench\Go\src\hello
然后我删除
hello
那么我必须将所有实用程序移动到另一个包文件夹吗?
我是否必须在hello包文件夹中仅保留单个
添加1
一个有用的参考:http://thenewstack.io/understanding-golang-packages/
添加2
经过几个简短的实验,我猜
因为我注意到了这些事实:
-
package xxx 声明不必与包含的包文件夹名称相同,例如yyy 。 -
但
import yyy 声明必须使用包文件夹路径yyy 。 -
使用包中的符号时,我们仍然必须使用
xxx.Symbol 而不是yyy.Symbol 。
添加3
为了证实我在ADD 2中的猜测,我这样做了:
(以pkg1 file1.go)
1 2 3 4 5 6 7 | 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)
1 2 3 4 5 6 7 | package main import"pkg1" func main() { pkg2.FA() //here, the FA is referenced via"pkg2" rather than the"pkg1". } |
以上2个文件可以编译运行。
但如果我改为:
(CMD1 main.go)
1 2 3 4 5 6 7 | 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: imported and not used:"pkg1" as pkg2
....\src\cmd1\main.go:6: undefined: pkg1 in pkg1.FA
为了双重确认,我用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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 |
所以到目前为止的结论是:
当声明的包名称与包文件夹名称不同时,包声明将用作包的备用名称。
相当于此,但隐含地:
1 | import pkg2"pkg1" |
顺便说一句,因为包声明没有反映在已编译的
- 请参见如何编写Go代码
-
顺便说一句:将实用程序函数保存在文件
utilities.go 中并且仍在package main 下是完全正常的。 Go中的包通常由几个文件组成,通常包含几种类型。
go文件在同一个包中AKA文件夹必须具有相同的包名。 唯一的例外是可以具有_test扩展的测试。 规则是1个文件夹,1个包因此同一个文件夹中所有go文件的包名称相同。
答案是肯定的,将"hello"包文件移动到它们自己的文件夹中,或者对同一目录中的所有文件使用相同的包名。
-
你真的是指将"utilities.go"移动到另一个文件夹吗? 让文件夹只保存
main.go 文件的文件夹看起来很笨重。 - utilities.go不是一个包的文件。 重要的是文件中的包名,你不能在同一个文件夹中有一个"hello"和一个"main"包并构建你的代码,这就是全部,这不是一个意见,这就是Go的工作方式。
-
我想我可以将
package main 放入utilities.go 并仍然将其保存在与main.go 相同的文件夹中。 Go仍将通过名称main 找到入口点。 -
事实证明,内置的
cmd\cgo 包确实为同一个包文件夹中的所有*.go 文件放置了package main 。 - 并没有真正改变你的问题。 一个文件夹中只有一个包。 我不管包裹的名称是什么。 你不能在同一个文件夹中有2个包。