Golang提案:取消99%的.go文件对package声明的强制要求

Golang提案:取消99%的.go文件对package声明的强制要求 大多数 .go 文件中的 package 部分是冗余的。这可以通过重用目录名来推断,或者匹配同级目录中的第一个条目。用 cmd//main.go 编写的 Go 应用程序可以自动推断出主包。

奇怪的是,流行的 Go 代码检查工具建议为包添加文档字符串,但只在一个随意的 .go 源文件中添加,而该文件与其他贡献于同一包的文件共存。复制、粘贴和维护重复的文档字符串并不…易于维护。

4 回复

一种解决方案是相应地限制目录和文件路径名称。

顺便提一下,值得发布一个检查工具来警告各种无效的文件路径字符,因为它们往往会破坏很多东西。

更多关于Golang提案:取消99%的.go文件对package声明的强制要求的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这个解决方案只能单向工作。对于那些你的文件系统不支持的包名怎么办?比如包名“Ω”?这是一个有效的包名,但并非所有文件系统都支持。不过,我可以创建一个名为“omega”的文件夹,然后将包命名为“Ω”,以获得更短的导入名称,这样就能在所有文件系统上无问题地支持了。

包声明独立于文件系统的要求。因此,你的包名可以包含特殊字符(例如Unicode符号),而你的文件系统可能不允许在目录名中使用这些字符。你的目录名可能使用与源文件不同的编码(ANSI…?)。你的包名是区分大小写的,而你的文件系统可能忽略文件夹名称的大小写。

你的文件系统也可能允许在目录名中使用符号,但这些符号对于包名是无效的(例如空格" "或连字符“-”)。

包声明使用源文件的编码为你的包提供了唯一的规范名称。按照惯例,你的目录名应该是你的文件系统(或者更准确地说,是所有相关维护者的文件系统)能够支持的、最接近此名称的近似值。

这是一个值得讨论的提案,但取消package声明会带来几个技术问题:

  1. 包推断歧义:当目录中存在多个包时(虽然不符合规范但技术上允许),编译器无法确定使用哪个包名。例如:
// 目录结构:
// mypkg/
//   foo.go      // package foo
//   bar.go      // package bar

// 当前Go允许这种结构(虽然不推荐)
// 取消package声明后,编译器无法处理这种情况
  1. 跨平台一致性:目录名在不同文件系统中有大小写敏感性差异,而Go包名是大小写敏感的。

  2. 工具链依赖:所有Go工具(go build、go test、gopls、静态分析工具)都需要修改解析逻辑,增加复杂度。

  3. 代码清晰性:显式的package声明提供了明确的代码组织意图,特别是在处理_test.go文件时:

// 当前明确区分:
// main.go
package main

// main_test.go
package main_test  // 或 package main

// 如果取消声明,测试文件的包归属变得模糊
  1. 导入路径解析:Go的导入路径基于目录结构,但包名可以不同。例如:
import "github.com/user/mypkg"  // 导入路径
// 但实际包声明可能是:
package mypackage  // 与目录名不同

对于文档字符串的问题,更好的解决方案可能是增强工具支持,而不是移除package声明。例如,go doc可以自动合并同一包中所有文件的文档,或者提供包级别的文档文件(如package.doc.go)。

当前的设计虽然有些冗余,但提供了明确的语义和更好的工具支持。

回到顶部