Go module 目录为什么带 ! 感叹号?

大家好,我是煎鱼。

前段时间二丫大佬反馈了一个较为细节的问题,当时在忙一下子没查阅出来。最近交流后有了新的验证和官方结论,获得一个新的小知识点,分享给大家。

该问题与 Go 模块的存储目录和方式有关。首先我们查看在本地 mod 目录下的相关目录。

如下图的模块存储路径:

bffc44339ff6624dbdcdd487cdf80382.png

认真一看,会发现一个神奇的现象。那就是有的文件夹名称是带 ! 感叹号的。但是包本身并没有这样命名。

如下图红框中的感叹号:

921b78066db3b14b2593285a8decbb4d.png

这是怎么回事,目录名乱码了吗,还是说是一种加解密的编码?

golang.org/x/mod 的官方文档下 Escaped Paths[1] 我们能够找到相关的解释。如下图:

6790a5d1e588a9d9774c2a68d6d0ca4e.png

这个问题的缘由是因为 Go 模块是从 OS 文件系统读取数据的,模块不能单纯的依靠 OS 文件系统来区分大小写,也不能依靠网络服务器去区分。

也就是说,我们无法单纯依靠文件系统将 rsc.io/QUOTErsc.io/quote 区分开来。(至少 Windows 和 macOS 是这样)

4f1bc659c85af096ecf730ca689c6a19.png

因此 Go 模块需要一种安全的转义方式,使大多数导入路径的结果保持不变,避免名称的冲突。

经过各方面的考量,Go 团队得出的安全转义的方式是:用感叹号替换每个大写字母,后面跟一个小写字母

例如:

github.com/Azure/azure-sdk-for-go ->  github.com/!azure/azure-sdk-for-go.
github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy
github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus.

注:Go 模块导入路径不允许使用 ! 感叹号 ,因此无需定义如何转义 ! 感叹号。

可能会有同学想说,全转大写或小写。这样其实也是不行的,因为会出现重名的情况,直接就覆盖了。

更甚者,例如:DataDog 这个模块,它随着时间的推移改变了大小写的命名,还改了几次。因此如果你 mod 目录下有多个版本,现在这种设计下,你会有一个 !d!a!t!a-!d!o!g 和一个 !data!dog 目录。

总结来讲,Go 模块(mod)的会将路径中的大写字母转换为相应的小写字母,并在前面加上感叹号,以避免在大小写不敏感的文件系统中发生大小写冲突。也就有了这看起来那么 “奇怪” 的目录名。

感觉神奇的 Go 知识又多掌握了一个!

推荐阅读

参考资料

[1]

Escaped Paths: https://pkg.go.dev/golang.org/x/mod/module#hdr-Escaped_Paths

关注和加煎鱼微信,

一手消息和知识,拉你进技术交流群👇

8b016db51ce3e17f5f3926cda14ba39c.jpeg

ec555ad7969a4618ff9c82b23e209a59.png

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

原创不易 点赞支持

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值