在 Go 中,包名称必须与最内层目录名称相同吗?

Pei*_* Li 7 package go package-name go-modules

注意这个问题是关于 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 pbpackage pa,并将导入从 更改"myproj/pa/pb""myproj/pa",然后在 main.go 中更改fmt.Print(pb.Greet)fmt.Print(pa.Greet),它将起作用。最里面的目录必须与包声明名称匹配吗?我的go版本是1.14.4

Gro*_*ify 6

在 Go 中,包名称必须与最内层目录名称相同吗?

它不必完全相同,但这是一个通用约定。除非有充分的理由,否则您不应该偏离它。

如果您想要不同的包名称和目录名称,可以使用带有文件的包子句的导入注释。

package <package_name> // import "<import_path>"
Run Code Online (Sandbox Code Playgroud)

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

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

  • 包裹名字:slides
  • 导入路径:google.golang.org/api/slides/v1

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

package slides // import "google.golang.org/api/slides/v1"
Run Code Online (Sandbox Code Playgroud)

这样,可以在调用代码中完成以下操作,这看起来很合理。

package <package_name> // import "<import_path>"
Run Code Online (Sandbox Code Playgroud)

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

在此示例中,您将使用:

package pb // import "myproj/pa"
Run Code Online (Sandbox Code Playgroud)

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

import pb "myprog/pa"
Run Code Online (Sandbox Code Playgroud)


ska*_*esh 5

在 Go 中,一个约定是包的名称应该等于其源目录的名称。

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

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

这样做的效果是单个目录只包含一个包。它在围棋中是如此基础,以至于你可以将其视为一个固定规则,尽管从技术上来说,它只是一个约定。


Pei*_* Li 5

经过一番尝试和错误后,我发现发生了什么事。包名称必须与最内层目录名称相同吗?不。

只需main.go执行以下操作就应该有效。

package main

import (
    "fmt"
    "myproj/pa"
)

func main() {
    fmt.Print(pb.Greet)
}
Run Code Online (Sandbox Code Playgroud)

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

package main

import (
    "fmt"
    pc "myproj/pa"
)

func main() {
    fmt.Print(pc.Greet)
}
Run Code Online (Sandbox Code Playgroud)

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

当然,不建议这样做,最好的做法仍然是不要这样做来迷惑人们。

  • 这个问题是问 Go 规范,而不是推荐或最佳实践。通过上面的例子,人们会理解 go 包是如何工作的,并且当看到一些第三个包有这样的东西时不再感到困惑。 (2认同)