注意这个问题是关于Go语言规范的,而不是最佳实践或建议。
我读过很多关于软件包的文章,但是我仍然不太理解目录和软件包名的关系。下面是我的例子。
我的项目结构就像下面的截图。当我执行go run ~/go/src/myproj/main.go
时,错误显示:
源代码\我的项目\主文件。转到:5:2:无法在以下任何位置找到软件包“paybaybay.com”:c:\go\源代码\我的项目\pa\pb(来自$GOROOT)C:\用户\terry\go\源代码\我的项目\pa\pb(来自$GOPATH)
但是如果我在p.go中把package pb
改成package pa
,把import从"myproj/pa/pb"
改成"myproj/pa"
,把main.go中的fmt.Print(pb.Greet)
改成fmt.Print(pa.Greet)
,就可以了,最里面的目录必须和包声明名匹配吗?我的go版本是1.14.4
4条答案
按热度按时间rekjcdws1#
在go中,一个约定是包的名字应该等于它的源目录的名字。
下面是Effective Go Blog的一个示例摘录:
另一个约定是包名是其源目录的基名;src/encoding/base64中的包被导入为"encoding/base64",但名称为base64,而不是encoding_base64和encodingBase64。
这样做的效果是一个目录中只包含一个包,这在go中是非常基本的,你可以把它看作是一个固定的规则,尽管从技术上讲,它只是一个约定。
4ioopgfo2#
在Go语言中,包名必须和最里面的目录名相同吗?
它不一定要完全相同,但这是一个共同的惯例。除非你有充分的理由,否则你不应该偏离它。
如果你想要一个不同的包名和目录名,你可以在文件的package子句中使用import注解。
这在文件结构不利于描述性名称时很有用,例如在文件路径中使用多个版本时。
例如,Google的客户端SDK使用如下路径:
slides
google.golang.org/api/slides/v1
为了支持这一点,文件的package子句如下所示:
通过这种方式,可以在调用代码中完成以下操作,这看起来很明智。
查看更多信息:https://github.com/googleapis/google-api-go-client/blob/master/slides/v1/slides-gen.go
在下面的示例中,您将使用:
如果您不使用package子句方法,编辑器可能会自动为您的代码添加别名,例如:
voj3qocg3#
包名不一定是包目录的基目录。go工具goimports在清理源文件的导入时,如果包名与基目录不匹配,实际上会将包名显示为导入的别名-a为了使导入代码看起来更有意义,但别名不是必需的--文件将在没有别名的情况下编译。当查看包的AST时,types.Package有一个返回包名的Name方法。当用www.example.com函数加载包时golang.org/x/tools/go/packages.Load,返回的 *packages.Package有一个同样返回包名的Name属性。这在按程序生成代码时非常有用。
gtlvzcf84#
经过一些试验和错误,我发现发生了什么。包名必须与最内层的目录名相同吗?不。
在
main.go
中,只需执行以下操作就可以了。我们也可以给予它一个别名,如下面的工作也.
也就是说,go中的package是一个声明了
package xxx
的文件目录,目录名在导入过程中很重要,目录是导入路径的一部分,但是导入文件中使用的是package xxx
中的xxx或者是xxx的别名。当然,做这样的事情是不建议的,但最好的做法是不要这样做来迷惑人。