24

I recently discovered that our company has a set of coding guidelines (hidden away in a document management system where no one can find it). It generally seems pretty sensible, and keeps away from the usual religious wars about where to put '{'s and whether to use hard tabs. However, it does suggest that "lines SHOULD NOT contain embedded multiple spaces". By which it means don't do this sort of thing:

foo    = 1;
foobar = 2;
bar    = 3;

Or this:

if      ( test_one    ) return 1;
else if ( longer_test ) return 2;
else if ( shorter     ) return 3;
else                    return 4;

Or this:

thing foo_table[] =
{
  { "aaaaa", 0 },
  { "aa",    1 },
  // ...
}

The justification for this is that changes to one line often require every line to be edited. That makes it more effort to change, and harder to understand diffs.

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.

What's your view on this?

4

14 回答 14

29

2008: Since I supervise daily merges of source code,... I can only recommend against it.

It is pretty, but if you do merges on a regular basis, the benefit of 'easier to read' is quickly far less than the effort involved in merging that code.

Since that format can not be automated in a easy way, the first developer who does not follow it will trigger non-trivial merges.

Do not forget that in source code merge, one can not ask the diff tool to ignore spaces :
Otherwise, "" and " " will look the same during the diff, meaning no merge necessary... the compiler (and the coder who added the space between the String double quotes) would not agree with that!

2020: as noted in the comments by Marco

most code mergers should be able to handle ignoring whitespace and aligning equals is now an auto format option in most IDE.

I still prefer languages which come with their own formatting options, like Go and its gofmt command.
Even Rust has its rustfmt now.

于 2008-09-19T13:53:04.697 回答
24

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.

Well, since making code understandable is more important than making diffs understandable, you should not be torn.

IMHO lining up similar lines does greatly improve readability. Moreover, it allows easier cut-n-pasting with editors that permit vertical selection.

于 2008-09-19T13:52:56.303 回答
19

我从不这样做,我总是建议不要这样做。我不在乎差异更难阅读。我确实很在意首先要花时间来做这件事,而且每当需要重新对齐线条时,都需要额外的时间。编辑具有这种格式风格的代码令人恼火,因为它经常变成一个巨大的时间槽,我最终花费更多的时间格式化而不是进行真正的更改。

我也质疑可读性的好处。此格式样式在文件中创建列。但是,我们不按列样式从上到下阅读。我们从左到右阅读。这些列分散了标准阅读风格的注意力,并将视线拉向下方。如果它们没有完全对齐,这些列也会变得非常难看。这适用于无关的空白,也适用于多个(可能不相关的)列组,这些列组具有不同的间距,但在文件中一个接一个地落下。

顺便说一句,我发现您的编码标准没有指定制表符或大括号的位置真的很奇怪。与使用(或不使用)列式格式相比,混合使用不同的制表符样式和大括号位置会损害可读性。

于 2008-09-19T15:58:56.140 回答
16

我从不这样做。正如您所说,有时需要修改每一行以调整间距。在某些情况下(例如上面的条件句),如果您取消间距并将块放在与条件句不同的行上,它将是完全可读的并且更容易维护。

此外,如果您的编辑器中有不错的语法高亮显示,那么这种间距实际上是不必要的。

于 2008-09-19T13:54:33.757 回答
11

在史蒂夫·麦康奈尔(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) 
. . .

虽然这不会

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

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

我相信差异是显而易见的。还有一些关于对齐延续线的讨论。

于 2008-09-19T14:01:58.323 回答
8

就我个人而言,我更喜欢以稍微难以阅读的差异为代价来获得更高的代码可读性。在我看来,从长远来看,对代码可维护性的改进——尤其是在开发人员来来去去的时候——是值得权衡的。

于 2008-09-19T13:55:31.430 回答
3

With a good editor their point is just not true. :)

(See "visual block" mode for vim.)

P.S.: Ok, you still have to change every line but it's fast and simple.

于 2008-09-19T13:51:46.757 回答
3

我尝试遵循两个准则:

  1. 尽可能使用制表符代替空格,以尽量减少重新格式化的需要。

  2. 如果您担心对修订控制的影响,请先进行功能更改,将其签入,然后仅进行外观更改。

如果在“外观”更改中引入了错误,则允许公开鞭打。:-)


2020-04-19 更新:天啊,这十几年的变化!如果我今天要回答这个问题,可能会是这样的:“请您的编辑器为您格式化代码和/或告诉您的差异工具在您进行外观更改时忽略空格。

今天,当我审查代码的可读性并认为通过不同的格式来提高清晰度时,我总是以“......除非编辑器自动这样做。不要与你的工具对抗。他们总是赢。”

于 2008-10-31T04:38:53.240 回答
2

我的立场是这是一个编辑器问题:虽然我们使用花哨的工具来查看网页并在文字处理器中编写文本,但我们的代码编辑器仍然停留在 ASCII 时代。它们尽可能地笨拙,然后,我们尝试通过编写花哨的代码格式化程序来克服编辑器的限制。

根本原因是您的编译器不能忽略代码中的格式化语句“嘿,这是一个表”,并且 IDE 不能动态创建源代码的视觉上令人愉悦的表示(即,没有实际更改一个字节码)。

一种解决方案是使用制表符,但我们的编辑器无法自动对齐连续行中的制表符(这会使很多事情变得容易得多)。为了增加侮辱性,如果您弄乱了标签宽度(基本上是任何东西!= 8),您可以阅读您的源代码,但没有其他任何人的代码,例如您使用的库附带的示例代码。最后,我们的差异工具没有选项“忽略空格,除非它很重要”,编译器也不能产生差异。

Eclipse 至少可以以表格方式格式化分配,这将使大量的全局常量更具可读性。但这只是沙漠中的一滴水。

于 2009-02-11T14:11:12.563 回答
1

您可以将差异工具设置为忽略空格(GNU 差异:-w)。这样,您的差异将跳过这些行,只显示真正的变化。非常便利!

于 2008-09-19T14:28:49.947 回答
1

如果您打算使用自动代码标准验证(即 CheckStyle、ReShaper 或类似的东西),那么这些额外的空间将使编写和执行规则变得非常困难

于 2008-09-19T14:00:03.650 回答
0

We had a similar issue with diffs at multiple contracts... We found that tabs worked best for everyone. Set your editor to maintain tabs and every developer can choose his own tab length as well.

Example: I like 2 space tabs to code is very compact on the left, but the default is 4, so although it looks very different as far as indents, etc. go on our various screens, the diffs are identical and doesn't cause issues with source control.

于 2008-09-19T13:53:37.080 回答
0

我喜欢第一个和最后一个,但不太喜欢中间。

于 2008-09-19T13:57:47.447 回答
-2

这正是善良的上帝作为制表符给出的原因——在行中间添加一个字符不会搞砸对齐。

于 2008-09-19T13:55:35.780 回答