代码格式化:对齐相似的行可以吗?

27

最近我发现我们公司有一套编码准则(藏在一个文件管理系统中,没有人能找到它)。它似乎是相当合理的,避免了关于'{''的放置以及是否使用硬制表符等通常的争论。然而,它建议“行不应包含多个空格”。这意味着不要做这样的事情:

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 },
  // ...
}

这样做的理由是更改一行通常需要编辑每一行。这使得更改变得更加费力,并且更难理解差异。

我犹豫不决。一方面,这样排列可以使重复的代码更易于阅读。另一方面,它确实使差异更难以阅读。

你对此有什么看法?


第一和第三个例子都很好,但我认为第二个可能需要将其分成多行。 - thomasrutter
14个回答

30

2008年:由于我每天都要监督源代码的合并... 我建议不要使用它。

它看起来很好,但如果你经常进行合并,那么“更易读”的好处很快就远小于合并该代码所需的工作量。

由于这种格式不能轻松自动化,第一个不遵循它的开发人员将触发复杂的合并。

不要忘记,在源代码合并中,无法要求diff工具忽略空格:

    否则,“”和“ ”在差异期间看起来相同,这意味着不需要合并...编译器(以及在字符串双引号之间添加空格的程序员)不会同意!

2020年:正如评论Marco指出的:

大多数代码合并工具应该能够处理忽略空格和对齐等号是现在大多数IDE的自动格式选项。

我仍然喜欢使用自带格式选项的语言,例如Go和其gofmt命令
甚至Rust现在也有自己的rustfmt


3
难道这不比那更糟吗?任何需要重新排列的编辑(实际上似乎比您希望的更频繁)都会给您带来一个差异,在这个差异中,整个代码块都会发生变化。这将立即导致一个不小的合并问题。 - Ned
1
终于!我开始觉得只有我一个人在思考这个问题 ;) 即使Agoston Horvath建议忽略空格,但并非所有版本控制工具都能够做到这一点,实际上情况比这还要糟糕。 - VonC
2
如果源代码控制系统无法忽略空格,那么这不是一个失败吗? - DisgruntledGoat
@DisgruntledGoat:我同意应该在版本系统中处理这个问题,但这意味着版本系统必须知道代码的含义。 - xtofl
请注意,上述答案仍然是谷歌搜索结果中的首要内容之一。它是在2008年编写的,大多数代码合并工具现在都可以处理忽略空格和对齐等号,这在大多数集成开发环境中已经成为自动格式化选项。 - Marco
@Marco 我同意。我已经将你的评论包含在答案中以增加可见性。 - VonC

26

我犹豫了。一方面,像这样排列可以使重复的代码更易于阅读。另一方面,它确实使差异更难阅读。

既然让代码易于理解比让变更易于理解更重要,那么你就不应该犹豫。

在我看来,对齐相似行确实大大提高了可读性。此外,它允许在支持垂直选择的编辑器中更轻松地剪切和粘贴。


一种妥协的方式是保留现有代码,但允许对新代码或已经“触及”的代码进行重新格式化。还有其他更改,例如按字母或数字重新排序列表,也可以适用这个论点。 - AlanKley

20

我从不这样做,而且我总是建议别这么做。我不在乎diffs(差异)更难阅读,我关心的是第一次进行此操作需要花费时间,并且每当行需要对齐时都需要额外的时间。编辑具有这种格式样式的代码非常令人恼火,因为它经常变成一个巨大的时间陷阱,我最终花费的时间比实际做出的更改还要多。

我还质疑这种格式的可读性。这种格式样式会在文件中创建列。但是,我们不会以列样式从上到下“阅读”,我们是从左到右阅读的。这些列分散了标准的阅读方式,将目光拉向下方。如果它们没有完全对齐,这些列也会变得非常丑陋。这适用于不必要的空格,也适用于具有不同间距但相继出现在文件中的多个(可能不相关的)列组。

顺便说一下,我觉得你的编码标准不指定缩进或括号放置方式真的很奇怪。混合使用不同的缩进样式和括号放置方式将远远损害可读性,而不是使用(或不使用)列样式格式。


我认为它有一个元规则,即在文件/模块/项目中坚持一种风格。无论如何,几乎没有人知道这个文档的存在 :) - Ned
1
我总觉得公司没有强制执行全局规则时很奇怪。允许人们使用任何风格意味着将代码从一个项目移动到另一个项目变得棘手。 - Derek Park
如果在另一个项目中有一组非常精心编写的函数,但是它们采用完全不同的风格,将它们放入我的项目中会带来问题。我要么必须混合风格,要么浪费时间重新格式化代码。 - Derek Park
调用漂亮打印器需要多长时间? - jwg

16

我从不这样做。正如你所说,有时需要修改每一行以调整间距。在某些情况下(比如上面的条件语句),如果你放弃空格并将块与条件语句分开放置在不同行上,则代码可以更容易阅读和维护。

此外,如果你的编辑器具有良好的语法高亮功能,这种间距实际上并不是必需的。


12

关于此问题,Steve McConnell 的经典著作——代码大全中有相关讨论。如果你还没有这本书,建议购买一本。在第一版书中(也是我手头的版本),该讨论出现在第426页和427页。


编辑:

McConnell建议在一组赋值语句中,将等号对齐以表示它们之间的关系。但他同时警告说不要将所有等号都对齐,因为这可能会在视觉上暗示存在并不存在的关系。例如,下面的写法是合适的:

Employee.Name  = "Andrew Nelson"
Employee.Bdate = "1/1/56"
Employee.Rank  = "Senator"
CurrentEmployeeRecord = 0

For CurrentEmployeeRecord From LBound(EmployeeArray) To UBound(EmployeeArray) 
. . .
< p >虽然这不会

Employee.Name         = "Andrew Nelson"
Employee.Bdate        = "1/1/56"
Employee.Rank         = "Senator"
CurrentEmployeeRecord = 0

For CurrentEmployeeRecord From LBound(EmployeeArray) To UBound(EmployeeArray) 
. . .

我相信区别是显而易见的。还有一些关于对齐延续行的讨论。


1
也许您可以提供一个简短的引用或总结讨论,以使答案更有帮助。 - kaa
8
在《代码大全》的后续修订中,麦康奈尔在这个建议上进行了180度的转变。他在第二版修订中提出的建议是:“不要将赋值语句的右侧对齐”。他承认这种对齐方式会略微增加可读性和理解性,但由于与此风格相关的巨大维护成本,这种轻微的增加是不合理的。 - David Hammen
@DavidHammen,很高兴你添加了那个评论;我完全不知道他在这一点上改变了他的建议。 - Onorio Catenacci
McConnell的书(第二版)中相关页面为第758页。 - agorf

8

个人而言,我更喜欢通过牺牲一些难以阅读的差异来提高代码的可读性。在我看来,长期来看,提高代码的可维护性(特别是在开发人员进出的情况下)值得这种权衡。


3

有一个好的编辑器,他们的观点就不正确了。 :)

(查看vim的“可视块”模式。)

P.S .:好吧,你仍然需要更改每一行,但这很快而简单。


3

我遵循两个准则:

  1. 尽可能使用制表符而不是空格,以最小化重新格式化的需要。

  2. 如果你担心对修订控制的影响,请先进行功能性更改,然后检查它们,再进行纯粹的格式更改。

如果在"纯粹的"更改中引入了错误,则可以公开斥责。 :-)


2020-04-19 更新:十二年后,事情变化多端!如果我今天回答这个问题,可能会说:"请让您的编辑器为您格式化代码和/或告诉您的差异工具在进行纯粹更改时忽略空格。

今天,当我审查代码的可读性并认为通过不同的格式来提高其清晰度时,我总是用"...除非编辑器自动执行此操作。不要与您的工具作斗争。他们总是赢得胜利。"


1
我本来想推荐这个的。我通常是反过来做的。首先只进行一些表面上的变化,让我熟悉一下代码并使其更易阅读。然后再进行功能性的改变。 - KANJICODER

2
我的观点是这是一个编辑器问题:虽然我们使用先进的工具查看网页和在文字处理器中编写文本,但我们的代码编辑器仍然停留在ASCII时代。它们像我们制造的那样愚蠢,然后,我们试图通过编写花哨的代码格式化程序来克服编辑器的限制。
根本原因是您的编译器无法忽略代码中的格式化语句,这些语句表明“嘿,这是一个表格”,IDE无法即时创建源代码的视觉上令人愉悦的表示形式(即实际更改一字节的代码)。
一种解决方案是使用制表符,但我们的编辑器无法自动对齐连续行中的制表符(这将使许多事情变得更加容易)。而且更让人恼火的是,如果您混淆制表符宽度(基本上是任何!= 8的东西),您可以阅读您的源代码,但不能阅读其他人的代码,例如与您使用的库一起提供的示例代码。最后,我们的差异工具没有“忽略空格,除非计数”的选项,编译器也无法生成差异。
Eclipse至少可以以表格形式格式化分配,这将使大量全局常量更易读。但这只是沙漠中的一滴水。

这是一个不错的想法,但我不确定它是否可行,否则最终只能在特定环境下编辑源代码。我认为ASCII的最低公共分母本质是一个巨大的优势。 - Ned
我认为是时候往上升一个级别了。如果我们有像下一代HTML或接近于今天的文字处理器所能做到的体面的XML编辑器,许多事情将突然变得可能:代码过滤和简单生成、良好的显示等。 - Aaron Digulla

1
如果您计划使用自动化代码标准验证(例如CheckStyle、ReShaper或类似工具),那么这些额外的空格将使编写和执行规则变得非常困难。

由于似乎没有人知道我们有一个标准,所以在我们的情况下这似乎相当不可能 :) - Ned
1
这正是为什么你需要自动化代码规范验证。开始使用它吧。 - Ilya Kochetov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接