代码格式化:将相似的行对齐可以吗?
最近,我发现我们公司有一套编码准则(隐藏在文档管理系统中,没人能找到它)。通常,这似乎非常明智,并且避免了通常的宗教战争,即在何处放置" {"以及是否使用硬标签。但是,它确实建议"行不应包含嵌入的多个空格"。通过这种方式,请不要执行以下操作:
foo = 1; foobar = 2; bar = 3;
或者这个:
if ( test_one ) return 1; else if ( longer_test ) return 2; else if ( shorter ) return 3; else return 4;
或者这个:
thing foo_table[] = { { "aaaaa", 0 }, { "aa", 1 }, // ... }
这样做的理由是,更改一行通常需要编辑每一行。这使得更改变得更加努力,并且很难理解差异。
我被撕毁了。一方面,像这样排列可以使重复的代码更容易阅读。另一方面,它确实使差异难以阅读。
我们对此有何看法?
解决方案
对于一个好的编辑,他们的观点是不正确的。 :)
(有关vim,请参见"可视块"模式。)
附注:好的,我们仍然需要更改每一行,但它既快速又简单。
I'm torn. On the one hand, lining up like this can make repetitive code much easier to read. On the other hand, it does make diffs harder to read.
好吧,由于使代码易于理解比使差异易于理解更为重要,因此我们不应该被撕裂。
恕我直言,将相似的行排成一行确实可以大大提高可读性。此外,它允许使用允许垂直选择的编辑器更轻松地进行剪切粘贴。
由于我负责日常的源代码合并,因此...我只能对此提出建议。
这很漂亮,但是如果我们定期合并,"轻松阅读"的好处将远远少于合并该代码所付出的努力。
由于无法轻松实现该格式的自动化,因此第一个不遵循该格式的开发人员将触发非平凡的合并。
不要忘记,在源代码合并中,我们不能要求diff工具忽略空格:
否则,""和""在比较期间看起来将相同,这意味着不需要合并...编译器(以及在字符串双引号之间添加空格的编码器)将不同意这一点!
在多个合同中,差异也存在类似的问题……我们发现选项卡最适合每个人。设置编辑器以维护选项卡,每个开发人员也可以选择自己的选项卡长度。
示例:我喜欢左侧的2个空格标签,代码非常紧凑,但默认值为4,因此尽管缩进等看起来很不相同。在我们的各种屏幕上,差异都相同并且不会源代码管理问题。
我从不这样做。如我们所说,有时需要修改每行以调整间距。在某些情况下(例如上述条件),如果我们消除了间距并将这些块与条件分开放在单独的行中,那么它将很容易阅读并且易于维护。
同样,如果我们在编辑器中突出显示了不错的语法,则这种间距实际上不是必需的。
就我个人而言,我更喜欢较高的代码可读性,但代价是稍微难于读取差异。在我看来,从长远来看,值得改善代码的可维护性(尤其是随着开发人员的加入和发展)。
这恰好是好主勋章给Tabs的原因-在行的中间添加一个字符不会弄乱对齐方式。
我喜欢第一个和最后一个,但是不喜欢中间。
如果我们打算使用自动代码标准验证(例如CheckStyle,ReShaper或者类似的东西),那么这些多余的空格将使编写和执行规则变得非常困难
史蒂夫·麦康奈尔(Steve McConnell)曾经使用过的《代码大全》(Code Complete)中对此进行了一些讨论。如果我们没有这本开创性著作的副本,请帮自己一个忙,买一本。无论如何,讨论是在第一版的426和427页上进行的,这是我所掌握的版本。
编辑:
麦康奈尔建议在一组分配陈述中对齐等号,以表明它们是相关的。他还告诫不要在一组作业中对齐所有等号,因为它可以在视觉上暗示没有关系的关系。例如,这将是适当的:
Employee.Name = "Andrew Nelson" Employee.Bdate = "1/1/56" Employee.Rank = "Senator" CurrentEmployeeRecord = 0 For CurrentEmployeeRecord From LBound(EmployeeArray) To UBound(EmployeeArray) . . .
虽然这不会
Employee.Name = "Andrew Nelson" Employee.Bdate = "1/1/56" Employee.Rank = "Senator" CurrentEmployeeRecord = 0 For CurrentEmployeeRecord From LBound(EmployeeArray) To UBound(EmployeeArray) . . .
我相信差异是显而易见的。也有一些关于对齐连续线的讨论。
我们可以将diff工具设置为忽略空格(GNU diff:-w)。
这样,差异将跳过这些行,仅显示实际更改。非常便利!
我从不这样做,我总是建议不要这样做。我不在乎差异很难阅读。我关心的是,这样做首先需要花费时间,并且每当必须重新对齐行时都需要花费额外的时间。编辑具有这种格式样式的代码非常令人讨厌,因为它通常会占用大量时间,并且我最终花费了更多的时间格式化而不是进行真正的更改。
我也对可读性好处提出了质疑。这种格式样式会在文件中创建列。但是,我们不会从上到下以列样式阅读。我们从左到右阅读。列分散了标准阅读样式的注意力,并向下拉动了眼睛。如果它们没有完全对齐,那么它们也会变得非常难看。这适用于无关的空格,但也适用于多个(可能是不相关的)列组,这些列组具有不同的间距,但在文件中一个接一个地排列。
顺便说一句,我发现编码标准没有指定制表符或者花括号的位置确实很奇怪。混合使用不同的制表符样式和花括号位置将比使用(或者不使用)列样式格式破坏可读性。
我尝试遵循两个准则:
- 尽可能使用制表符代替空格,以最大程度地减少重新格式化的需要。
- 如果我们担心对版本控制的影响,请先进行功能更改,将其检入,然后仅进行外观更改。
如果在"美容"更改中引入了错误,则可以公开鞭打。 :-)
我的立场是,这是一个编辑器问题:虽然我们使用精美的工具查看网页,并且在文字处理器中编写文本时,我们的代码编辑器仍然停留在ASCII时代。它们尽我们所能而变得愚蠢,然后,我们尝试通过编写奇特的代码格式化程序来克服编辑器的局限性。
根本原因是编译器无法忽略代码中的"嘿,这是一个表"的格式声明,并且IDE不能动态地创建源代码的视觉效果表示(即,如果不实际更改,代码的字节)。
一种解决方案是使用制表符,但我们的编辑器无法自动将制表符连续对齐(这会使很多事情变得更加容易)。为了增加侮辱性的伤害,如果我们弄乱了制表符的宽度(基本上是!= 8),那么我们可以阅读源代码,而从其他任何人那里都看不到代码,例如,所用库附带的示例代码。最后,我们的diff工具没有选项"忽略空格,除非它计数",并且编译器也不会产生diff。
Eclipse至少可以以表格的形式格式化分配,这将使更多的全局常量集更具可读性。但这只是沙漠中的一滴水。