Go 透明文件夹的特性,有没有必要加?

大家好,我是煎鱼。

在 Go 语言中,我们一般会用模块(Module)和包(Package)来组织我们的项目、库的目录和代码结构。

今天给大家分享一个面向包这块的新提案,看看是否合适加进 Go 特性中?

前置知识:模块和包

具体来讲,模块(Module)就是 go mod 的应用。我们最常接触到的是以下命令:

perl 复制代码
mkdir my-project
cd my-project
go mod init github.com/eddycjjy/my-project

在执行了 go mod init 后会生成 go.mod 文件,如下所示:

go 复制代码
// go.mod
module github.com/eddycjy/my-project

go 1.21.1

这就是这个项目的模块。

对应到包(Package)中,会更加的直接和显性。我们一般会创建类似如下的目录结构:

css 复制代码
<my-project>
  -<cli>
    --cli.go
  -<internals>
    --internals.go
  --go.mod
  --main.go

Go 文件中的 package name,存在明确的约定俗成的标准,需要和目录名称保持一致。例如:

go 复制代码
// internals.go
package internals

import "fmt"

func Hello() {
 fmt.Println("你好,煎鱼!")
}

如果在其他地方中导入该包,则为:

go 复制代码
import (
 ...
 "github.com/eddycjy/my-project/internals"
)

以上就是模块和包的基础前置知识。我们接下来正式进入提案的正题。

提案:透明文件夹

针对 Go 程序的组织结构管理,最近社区有个同学提出了一个新提案:

在 Go 里文件夹默认与包(Package)的关系是划等号的。虽然这很方便,但是提案作者反馈:在某些情况下,我们需要通过文件夹来实现纯粹的组织和可读性目的,而不想引入新的包

为此提出了 "透明文件夹" 的概念,通过使用诸如 Next.js 应用程序路由器中看到的 (folder)_folder 之类的语义来表示。

这些文件夹可以在不创建新软件包的情况下组织软件包内的文件。它们将与软件包的根目录保持链接。

例子如下:

go 复制代码
myapp
  main.go
  myTypes.go
  (routes)
     handleRoot.go
     handleMultipart.go
     ...
  db
     connect.go
     dbTypes.go
     (auth)
         strategy1.go
         strategy2.go
         ...

可以看到这个例子,他使用 (folder) 的方式来表示透明文件夹。例如:(routes)(auth),这样他就不需要再细分不同的 package name,统一用 myapp 和 db 的包名就能进行引用。

简单来讲,该提案的实现方式是:通过将工程中 package name 和实体文件夹目录的作用分割开,目的是:提供一种纯粹的代码组织方式。

一些争议

其实类似的场景诉求,我有一个朋友曾经听几个同事吐槽过。但一般会是在比较大的 Go 项目中,例如出现以下场景:

css 复制代码
myapp
  service
    a-service
    b-service
    c-service
    ...

会认为这样 package 切割的比较碎,但是不区分开。多了后在代码结构上又很容易繁杂化。所以会想有一种纯碎的代码组织方式。

争议也是有不少的。因为他对语言的 ROI 并不是太高,变动的东西(例如:工具、IDE、tests 等)会比较多。

只需将文件命名为:aaa-foo.go aaa-bar.go bbb-foo.go bbb-bar.go,而不是 aaa/foo.go aaa/bar.go bbb/foo.go bbb/bar.go。也能达到类似的效果。

也有表示添加透明子文件夹会让一切变得更加复杂,却没有任何好处。把文件放在它们应该在的地方就可以了。现在已经在其他语言中看到过这种替代方法,很糟糕。

总结

这个提案本身的出发点很常见,因为 package name 和代码目录结构绑定了,会导致在设计代码结构时会有些受限,最终受此引导拆 package 来形成结构化。

如果盲目的添加透明文件夹,反而会出现一个尴尬的问题。因为 Go 语言在这块是非常直接的,添加了这类模式,大家反而会没法笃定,要去看看项目的代码结构才能确定。

我认为反而会导致可读性会有所下降。

文章持续更新,可以微信搜【脑子进煎鱼了】阅读,本文 GitHub github.com/eddycjy/blo... 已收录,学习 Go 语言可以看 Go 学习地图和路线,欢迎 Star 催更。

Go 图书系列

推荐阅读

相关推荐
Grassto1 小时前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto2 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室3 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题3 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo
啊汉4 天前
古文观芷App搜索方案深度解析:打造极致性能的古文搜索引擎
go·软件随想
asaotomo5 天前
一款 AI 驱动的新一代安全运维代理 —— DeepSentry(深哨)
运维·人工智能·安全·ai·go
码界奇点6 天前
基于Gin与GORM的若依后台管理系统设计与实现
论文阅读·go·毕业设计·gin·源代码管理
迷迭香与樱花6 天前
Gin 框架
go·gin
只是懒得想了6 天前
用Go通道实现并发安全队列:从基础到最佳实践
开发语言·数据库·golang·go·并发安全
fenglllle7 天前
使用fyne做一个桌面ipv4网段计算程序
开发语言·go