每个Go文件都以package <something>.
据我所知 - 这可能是我缺少一些信息的地方 - 只有两个可能的值<something>:它所在的目录名称*,或main.如果是main,该目录中的所有其他文件也只能有main.如果是其他内容,则项目不一致/违反惯例.
现在,如果它是目录的名称,则它是多余的,因为相同的信息就是在目录的名称中.
如果是main,那就没用了,因为据我所知go build,没有办法告诉"请建立所有 main包裹".
*换句话说,一个目录是一个包.
您"拥有"的缺失信息是包名称不必与目录名称相同.
使用文件夹名称以外的包名称是完全正常的.如果这样做,您仍然必须根据目录结构导入包,但在导入后,您必须通过package子句中使用的名称来引用它.
例如,如果您有一个文件夹$GOPATH/src/mypck,并且在其中有一个文件a.go:
package apple
const Pi = 3.14
Run Code Online (Sandbox Code Playgroud)
使用这个包:
package main
import (
"mypck"
"fmt"
)
func main() {
fmt.Println(apple.Pi)
}
Run Code Online (Sandbox Code Playgroud)
就像你被允许使用相对导入但不可取,你可以使用其他包含文件夹的包名,但这也不建议避免进一步的误解.
请注意,规范甚至不要求属于同一个包的所有文件都在同一个文件夹中(但它可能是一个实现要求).规范:包子句:
共享相同PackageName的一组文件形成包的实现.实现可能要求包的所有源文件都位于同一目录中.
简单.包名称是Go 标识符:
identifier = letter { letter | unicode_digit } .
Run Code Online (Sandbox Code Playgroud)
这允许在标识符中使用unicode字母,例如??在Go中是有效的标识符.Go不是处理文件夹和文件名,而是由操作系统处理,不同的文件系统有不同的限制.实际上有许多文件系统不允许所有有效的Go标识符作为文件夹名称,因此您将无法为您的软件包命名,否则语言规范将允许.
因此,一方面并非所有有效的Go标识符都可以是有效的文件夹名称.另一方面,并非所有有效的文件夹名称都是有效的Go标识符,例如go-math在大多数(所有?)文件系统中是有效的文件夹名称,但它不是有效的Go标识符(因为标识符不能包含短划线-字符).
可以选择使用与其包含文件夹不同的包名称,您可以选择真正命名包,语言规范允许的内容,无论底层操作和文件系统如何,并将其放在名为底层操作系统的任何文件夹中.文件系统允许 - 无论包名称如何.
包的名称不必与目录名一致.可以package foobar在目录中xyz/go-foobar.在这种情况下,xyz/go-foobar成为导入路径,但用于质量标识符(函数,类型等)的包名称将是foobar.
这是一个让它更具体的例子:我创建了一个测试包http://godoc.org/github.com/dmitris/go-foobar(来源:https://github.com/dmitris/go-foobar) - 你从文档页面可以看出,导入路径是"github.com/dmitris/go-foobar",但包名是foobar,所以你可以调用它提供的函数foobar.Demo()(不是go-foobar.Demo()).
一个类似的现实例子 - NSQ Messaging平台的导入路径是"github.com/nsqio/go-nsq",而软件包名称是"nsq":http://godoc.org/github.com/nsqio/ go-nsq.但是,出于用户友好性和简单性的考虑,标准和建议的做法是尽可能保持导入路径的最后部分和包名称相同.
package main它没有用 - 它告诉Go编译器创建一个可执行文件而不是.a库文件(带go install或go get; go build丢弃编译结果).可执行package main文件以放置文件的目录名命名.再一个具体的例子 - 我做了一个测试程序https://github.com/dmitris/go-foobar-client,你安装它,go get github.com/dmitris/go-foobar-client你应该得到一个go-foobar-client可执行文件放在你的$ GOPATH/bin目录中.它来自package main放置文件的目录名,Go编译器从中获取可执行文件的名称..go包含该main()函数的文件的文件名并不重要 - 在上面的示例中,我们可以重命名main.go为client.go或其他内容,但只要调用封闭目录go-foobar-client,就会生成可执行文件的命名方式.
关于Go软件包的附加可访问性和实用性阅读,我推荐Dave Cheney的文章"建立Go项目的五个建议" http://dave.cheney.net/2014/12/01/five-suggestions-for-setting一个项目.