QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

关于 Tab 与空格之争,暴躁老哥 Linus 又有新指示!

  • 2024-04-22
    北京
  • 本文字数:2632 字

    阅读完需:约 9 分钟

大小:1.22M时长:07:05
关于Tab与空格之争,暴躁老哥Linus又有新指示!

Tab 与空格之争是个延续自 Unix 时代的问题。

Linus 故意“复杂化”Linux Kconfig 中的缩进机制

 

长久以来,Linus 一直以公开、尖锐提出反馈意见而闻名。尽管自 2018 年以来他一直在努力控制情绪,但从他最近回复自己强烈反对的提案来看,我们熟悉的那位暴躁老哥又回来了,只是用词文明了许多。这次他针对的,是 Tab 问题。

 

近日,Linux 内核的最新候选版本内核 6.9-rc4 正式发布,在常见的驱动程序与 bug 修复部分,不仅对 bcachefs 进行了更多的调整和优化,还针对最近发现的 Spectre 式本机分支历史注入数据泄漏问题,提供了有效的缓解措施,以确保系统的稳定性和安全性。


新版本中最引人注目的变化莫过于 Linus 本人所做出的配置文件变量调整。他针对“Kconfig”进行了优化,主动添加了一些隐藏 Tab,将原本的空格缩进改为 Tab 缩进。这一举措旨在消除那些质量低下的解析器,从而提升整体性能和稳定性。


具体来讲,在下面这段内核源代码中:


    default 12 if PAGE_SIZE_4KB    default 13 if PAGE_SIZE_8KB    default 14 if PAGE_SIZE_16KB    default 15 if PAGE_SIZE_32KB    default 16 if PAGE_SIZE_64KB    default 18 if PAGE_SIZE_256KB
复制代码


default 值与整数值之间的字符现在为八字符宽度的 Tab 缩进。但由于恰好落在 Tab 边界的末端,所以其显示成了一个空格字符。


Kconfig 是用于控制内核构建系统的配置语言,与许多其他越位规则语言一样,它会使用缩进来分隔各代码块。Linus 发现一段特定代码更改 commit d96c36004e31,其作用只有一个:修复 FTRACE_RECORD_RECURSION_SIZE 条目,用空格字符替换 Tab 符,这能帮助 Kconfig 解析器正确读取文件。

 

在此更改中,他故意让内核构建配置文件中的缩进机制变得更复杂,以迫使此类解析工具的作者随之改进。Linus 的意见是“主动添加一些隐藏的 Tab”,这种故意让 Tab 检测失败的作法已经清晰表达了他的立场。他还写道,“除非必要,否则我不希望多此一举。但现实中的确出现了不少这类愚蠢的工具,所以我只能选择这种方式”。Linus 本人对此做出的解释是:我还是觉得应该做出修改。因为如果无法将 Tab 解析为空格,那些工具就没资格解析内核 Kconfig 文件。

 

据悉,Linus 的隐藏 Tab 提议出现在 Linux 内核 6.9 的第四个候选版本当中。Linus 写道,该版本在发布当周“并没有发生什么特别的状况”。

 

值得一提的是,这次 Linus 并没有态度激烈地“口吐芬芳”,而是故意、甚至可以说是恶意使用更复杂的缩进来恶心那些效果不佳的解析工具。他认为差劲的工具就该被淘汰掉,只有更合适、更强大的工具才能生存……而且这种方式也不会直接伤害任何人的感情。

Tab 与空格之争

 

Tab 与空格之争是个延续自 Unix 时代的问题,虽然事情不大,但却永远无法用标准、格式之类的简单方式得到解决。如果真要把问题放大,那可能需要投入无穷无尽的资源和人力。

 

而 Linux 内核项目一直坚持自己的编码风格,也就是编码圣经《C 程序设计语言》的作者 Kernighan 与 Ritchie 提出的原则——如果要提交内核代码,最好使用 Tab(理想情况下为八字符的 Tab,而这种设计又继承自当初的电传打字机与行式打印机)。

 

在现实编程中,缩进使用 Tab 还是空格的问题不仅在普通程序员中存在争议,很多技术大佬也会参与这项讨论。

 

在接受 Reddit 采访时,微软创始人比尔·盖茨果断站队了 Tab 阵营。他表示,“自己更喜欢用 Tab,因为我想让 column 排成一行。对于某些 Word 文档,我用 Tab,如此,当我想要修改部分内容,需要返回并编辑时,Tab 显然更容易操作”。

 

而在 HBO 的喜剧片《硅谷》第三季中,不同的缩进风格甚至导致两位程序员分手。两位程序员一边编程一边约会,男方忍受不了女方使用空格键缩进,认为 Tab 键更节省文件体积,最终二人不欢而散。

冲突核心

 

编程时需要用缩进来建立视觉层次结构,从而改善代码的结构和可读性。缩进主要用于显示哪些代码行属于条件、循环、方法或者类。除了显示范围之外,缩进还可以用于拆分较长的逻辑操作。包含复杂条件的三元运算符可以用缩进将其表达式拆分成几行,以便开发者加以区分。链式方法调用(如果超过两个)可以在新行上缩进,借此表明它们属于同一操作流。

 

很明显,缩进是一种专门针对人类的工具,目的就是方便开发者阅读和编写代码。每行开头添加的这些空格对于编译器其实没什么实际影响(Python 除外)。

 

而围绕 Tab 符和空格符掀起的争论,其关键并不在于缩进几个字符最合适,而是使用哪种字符更好。

 

Tab 符

 

按下键盘上的 Tab 键就能直接输出 Tab 符,解析器会将其解释成一定数量的空格,通常是 4 个或者 8 个空格符。使用 Tab 格式的文件通常较小,因为一个 Tab 符就能代表多个空格,而且现如今处理起来也没什么难度。

 

Tab 符的长度在不同 IDE 和编辑器中的解释各不相同,而且可以配置调整。所以哪怕是希望一个 Tab 对应 6 个空格,也完全没有问题。这种可定制性,使得 tab 符成为不想眼花的开发者们最支持的选项。

 

Tab 符发挥的是描述作用,负责告知编辑器应该添加的缩进量。但如果呈现则由代码的阅读者来决定。在 Tab 派开发者心中,Tab 符就是用来缩进的,而空格符专门负责对齐。

 

空格符

 

空格派的主要观点在于一致性。不同平台与编辑器往往有着不同的 Tab 缩进量。由于其可配置性,我们很难保证自己编写的代码始终能被读取为相同结果。如果我们从某处复制/粘贴来了代码,那么由于缩进量的差异,实际代码可能看起来一团糟。

 

但在任何编辑器和平台上,空格将始终只是空格。不同于 Tab 符的可配置性,空格在任何位置上的显示效果都一致且稳定。也就是说无论如何设置 Tab 符,代码都将显示为相同的格式。

 

不同之处在于,这个决定仅由代码编写者做出,而非阅读者做出。空格在代码本身中被固化为一种格式决策,而其他开发者在阅读时无法调整、只能被动接受。

问题的核心不止于技术

 

Tab 与空格之争的关键在于该用哪种字符表示缩进。这场争论不止于技术,更是编程理念的体现。

 

换言之,就是缩进方式到底该由谁来指定。

 

Tab 符的支持者们认为显示结构应该由阅读者来指定。空格派倡导者则主张应该由编写者指定,毕竟这样更有利于保持一致性。两派都有狂热的支持者,他们各自掌握着充分的论据,但最终如何选择仍然由开发者自己决定。

 

此前,Google 程序员 Felipe Hoffa 曾分析了 GitHub 上的 40 万个代码库,10 亿个文件,总共 14TB 数据,这些文件不包含重复的文件和代码行数低于 10 行的文件,分析后发现空格键远比 Tab 键流行。



那么问题来了,你是 Tab 派还是空格派?

 

参考链接:

https://www.theregister.com/2024/04/16/torvalds_complicates_his_indents/

https://alexkondov.com/indentation-warfare-tabs-vs-spaces/

2024-04-22 14:303988

评论 2 条评论

发布
用户头像
我是蛋黄派
2024-04-28 16:51 · 广东
回复
该评论已删除
2024-04-28 18:11 · 北京
回复
用户头像
我是中间派
2024-04-26 09:09 · 广东
回复
没有更多了
发现更多内容

web前端培训JS解构赋值知识点分享

@零度

JavaScript web前端

使用vite创建vue3项目

隔壁的猫

前端 Vite2 vue3.2 3月月更

OpenHarmony 标准系统 HDF 框架之 I2C 驱动开发

Anna

开源 后端 直播 OpenHarmony I2C

浅谈SaaS多租户数据隔离和共享

数商云

SASS

谷歌云对象存储攻防

火线安全

云原生 云安全 云存储

EventBridge 事件总线及 EDA 架构解析

阿里巴巴云原生

DevSecOps邂逅云原生:云原生时代下的持续安全

火线安全

DevOps 云原生 云安全 云原生安全

关于React项目本地开发设置Https的过程

隔壁的猫

前端 React 3月月更

4种典型限流实践保障应用高可用|云效工程师指北

阿里云云效

云计算 阿里云 云原生 系统安全 研发

数字经济“双碳”目标下,“东数西算”数据中心为何依靠液冷散热技术节能减排?

GPU算力

东数西算 GPU服务器

数盾科技加入,携手龙蜥社区提升网络安全整体防护能力

OpenAnolis小助手

开源 网络安全 数盾科技 密码算法

大数据培训Flink中常见问题定位

@零度

大数据 flink

有奖互动|中国信通院联合 OceanBase 邀您参加《数据库发展研究报告(2022)》调研问卷

OceanBase 数据库

碰到运维难题怎么快速解决?有工具推荐吗?

行云管家

运维 网络运维 IT运维 服务器运维

超级app+轻应用=未来?

發財KK

移动应用 轻应用 快应用 App生态

Android技术分享|【自定义View】实现Material Design的Loading效果

anyRTC开发者

android 音视频 移动开发 自定义view loading

尚硅谷监控告警系统(Zabbix)视频教程发布

@零度

大数据 zabbix

关于 Nvm

隔壁的猫

node.js 前端 NVM 3月月更

云原生安全实践

火线安全

云原生 安全 云安全

NextArch基金会微服务技术组成立,腾讯为创始单位之一

科技热闻

性能指标、响应时间、并发量…聊聊性能优化的衡量指标

华为云开发者联盟

性能优化 高并发 响应时间 性能指标 并发量

TypeScript里string和String,真不是仅仅是大小写的区别

华为云开发者联盟

JavaScript typescript string ts

Flink 在米哈游的落地实践

Apache Flink

大数据 flink 编程 流计算 实时计算

平衡树:为什么Redis内部实现用跳跃表

华为云开发者联盟

redis 数据结构 集合 跳跃表 平衡树

DevSecOps: 让大家都 Happy 的安全软件构建模式

火线安全

云原生 软件架构 DevSecOps 云安全

云计算时代,好用的IT运维软件我给推荐行云管家!

行云管家

云计算 运维 网络运维 IT运维

负载均衡,你想了解的全在这里!

博文视点Broadview

贝壳Flutter UI 自动化测试原理与实践 - 已开源

贝壳大前端技术团队

flutter 测试 UI自动化 贝壳找房

阿里云 VPC 内网性能测试最佳实践

阿里巴巴云原生

产品经理必看的高效产品文档撰写指南

小炮

产品文档

java培训SpringBoot性能优化

@零度

Java springboot

关于Tab与空格之争,暴躁老哥Linus又有新指示!_后端_凌敏_InfoQ精选文章