为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中,包名是否必须与最里面的目录名相同?

在 Go 中,包名是否必须与最里面的目录名相同?

Go
喵喵时光机 2022-06-13 16:05:35
注意这个问题是关于 Go 语言规范而不是最佳实践或推荐。看了很多包的文章,还是不太明白目录和包名的关系。这是我的例子。我的项目结构如下图所示。当我这样做时go run ~/go/src/myproj/main.go,错误说:src\myproj\main.go:5:2: 在以下任何位置都找不到包“myproj/pa/pb”:c:\go\src\myproj\pa\pb(来自 $GOROOT)C:\Users\terry\ go\src\myproj\pa\pb(来自 $GOPATH)但是,如果我在 p.go 中更改package pb为package pa,并将导入从更改"myproj/pa/pb"为"myproj/pa",然后在 main.go 中更改fmt.Print(pb.Greet)为fmt.Print(pa.Greet),它将起作用。最里面的目录是否必须与包声明名称匹配?我的 go 版本是 1.14.4
查看完整描述

4 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

在 go 中,约定是包的名称应该与其源目录的名称相同。

例如,以下是Effective Go 博客的摘录:

另一个约定是包名是其源目录的基名;src/encoding/base64 中的包被导入为“encoding/base64”,但名称为 base64,不是 encoding_base64,也不是 encodingBase64。

这具有单个目录仅包含一个包的效果。它在围棋中是如此基础,您可以将其视为固定规则,尽管从技术上讲,它只是一个约定。


查看完整回答
反对 回复 2022-06-13
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

在 Go 中,包名必须与最里面的目录名相同吗?

它不必相同,但它是一个常见的约定。除非你有充分的理由,否则你不应该偏离它。

如果你想要一个不同的包名和目录名,你可以在文件的包子句中使用 import 注释。

package <package_name> // import "<import_path>"

这很有用,您的文件结构不利于描述性名称,例如,如果在文件路径中使用多个版本。

例如,Google 的客户端 SDK 使用如下路径:

  • 包裹名字:slides

  • 导入路径:google.golang.org/api/slides/v1

为了支持这一点,文件的包子句如下:

package slides // import "google.golang.org/api/slides/v1"

这样一来,在调用代码中就可以进行如下操作,看起来合情合理。

package main


import(

    "google.golang.org/api/slides/v1"

)


func main() {

    fmt.Println(slides.PresentationsScope)

}

在此处查看更多信息:https ://github.com/googleapis/google-api-go-client/blob/master/slides/v1/slides-gen.go


在此处的示例中,您将使用:


package pb // import "myproj/pa"

如果您不使用包子句方法,编辑器可能会自动为您的代码添加别名,例如:


import pb "myprog/pa"


查看完整回答
反对 回复 2022-06-13
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

包名不必是包目录的基础。go 工具 goimports 在清理源文件的导入时,实际上会采用包名称并将其显示为导入的别名,如果它与基础不匹配 - 使导入代码看起来更有意义但别名不是必需的 - 没有它,文件将编译。查看包的 AST 时, *types.Package 有一个 Name 方法,它返回包名。当使用 golang.org/x/tools/go/packages.Load 函数加载包时,返回的 *packages.Package 有一个 Name 属性,该属性也返回包名。这在按程序生成代码时非常有用。



查看完整回答
反对 回复 2022-06-13
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

经过一些试验和错误,我发现了发生了什么。包名称必须与最里面的目录名称相同?不。


main.go只需执行以下操作即可。


package main


import (

    "fmt"

    "myproj/pa"

)


func main() {

    fmt.Print(pb.Greet)

}

我们也可以给它一个别名,如下所示也可以。


package main


import (

    "fmt"

    pc "myproj/pa"

)


func main() {

    fmt.Print(pc.Greet)

}

所以这意味着,go 中的 package 是一个带有package xxx声明的文件目录。目录名称在导入过程中很重要。该目录是导入路径的一部分。但是在导入的文件中使用的是 xxx inpackage xxx或该 xxx 的别名。


当然,不建议做这种事情,但最好的做法还是不要这样做来迷惑人。


查看完整回答
反对 回复 2022-06-13
  • 4 回答
  • 0 关注
  • 871 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号