6

Code Complete表示,始终使用块标识符是一种很好的做法,既是为了清晰起见,也是作为一种防御措施。

自从读了那本书后,我就一直虔诚地这样做。有时它似乎过分,如下面的例子。

Steve McConnell 坚持始终使用区块标识符是否正确?您会使用其中的哪一个?

//naughty and brief
with myGrid do
  for currRow := FixedRows to RowCount - 1 do
    if RowChanged(currRow) then
      if not(RecordExists(currRow)) then
        InsertNewRecord(currRow)
      else
        UpdateExistingRecord(currRow);

//well behaved and verbose
with myGrid do begin
  for currRow := FixedRows to RowCount - 1 do begin
    if RowChanged(currRow) then begin
      if not(RecordExists(currRow)) then begin
        InsertNewRecord(currRow);
      end  //if it didn't exist, so insert it
      else begin
        UpdateExistingRecord(currRow);
      end;  //else it existed, so update it
    end;  //if any change
  end;  //for each row in the grid
end;  //with myGrid 
4

15 回答 15

10

我一直遵循“乖巧而冗长”的风格,除了结尾处那些不必要的额外注释。

不知何故,能够更快地查看代码并从中理解它更有意义,而不是必须花费至少几秒钟才能破译哪个块在哪里结束。

提示:C# 跳转开始和结束的 Visual Studio KB 快捷方式:Ctrl + ]

如果您使用 Visual Studio,那么在块的开头和结尾处为 C# 使用花括号也有帮助,因为您有一个 KB 快捷方式可以跳转到开头和结尾

于 2009-07-21T18:49:41.050 回答
7

我会使用我公司为其编码标准设定的任何标准。

话虽如此,我更喜欢使用第二个更详细的块。它更容易阅读。但是,在某些情况下,我可能会省略块结尾的注释。

于 2009-07-21T18:49:54.373 回答
7

就个人而言,我更喜欢第一个,因为恕我直言,“结束”;不要告诉我太多,一旦一切都接近了,我可以通过身份告诉我什么时候发生。

我相信块在有大型语句时更有用。您可以采用混合方法,在其中插入一些“开始...结束;”并注释它们的结尾(例如,将其用于 with 和第一个 if)。

恕我直言,您还可以将其分解为更多方法,例如,部分

  if not(RecordExists(currRow)) then begin
    InsertNewRecord(currRow);
  end  //if it didn't exist, so insert it
  else begin
    UpdateExistingRecord(currRow);
  end;  //else it existed, so update it

可以在单独的方法中。

于 2009-07-21T18:52:06.053 回答
5

我认为这在一定程度上取决于情况。有时你只是有这样的方法:

void Foo(bool state)
{
    if (state)
        TakeActionA();
    else
        TakeActionB();
}

我不明白如何使它看起来像这样:

void Foo(bool state)
{
    if (state)
    {
        TakeActionA();
    }
    else
    {
        TakeActionB();
    }
}

完全提高了可读性。

于 2009-07-21T18:56:19.850 回答
4

我是一名 Python 开发人员,所以我认为不需要块标识符。没有他们我很开心。缩进对我来说已经足够了。

于 2009-07-21T19:12:36.510 回答
2

块标识符不仅更易于阅读,而且如果您更改 if else 逻辑中的某些内容或只是添加一行并且没有识别出该行不在同一个逻辑块中,那么它们更不容易出错,那么其余代码.

我会使用第二个代码块。第一个看起来更漂亮,更熟悉,但我认为这是语言问题,而不是块标识符

如果可能的话,我会使用 checkstyle 来确保使用括号。

于 2009-07-21T18:54:28.810 回答
1

如果我没记错的话,CC 也给出了一些关于评论的建议。特别是关于不重写代码在注释中的作用,而是解释它为什么这样做。

于 2009-07-21T18:50:58.973 回答
1

我会说他是对的,只是因为如果缩进不正确,仍然可以正确解释代码。当我浏览代码时,我总是希望能够找到循环的开始和结束块标识符,而不是依赖适当的缩进。

于 2009-07-21T18:52:43.213 回答
1

它永远不会总是一种方式或另一种方式。因为我相信自己,我会使用更短、更简洁的风格。但是,如果您所在的团队环境并非每个人都具有相同的技能并且可维护性很重要,那么您可能希望选择后者。

于 2009-07-21T18:53:49.653 回答
1

我的下意识反应将是第二个列表(就像每个人都在说的那样,从行尾删除了重复的评论),但在更深入地考虑之后,我会选择第一个加上一两行有用的事先评论解释发生了什么(如果需要)。显然,在这个玩具示例中,甚至可能不需要简洁答案之前的注释,但在其他示例中可能需要。

屏幕上的代码更少(但仍然可读)且易于理解,有助于为 IMO 代码的未来部分腾出空间。

于 2009-07-21T19:00:26.350 回答
1

我和那些喜欢更简洁代码的人在一起。

看起来更喜欢冗长的版本而不是简洁的版本更多的是个人选择,而不是普遍适用性。(嗯,在公司内部,它可能成为(迷你)通用规则。)

这就像过多的括号:有些人喜欢(F1 and F2) or ((not F2) and F3)or (A - (B * C)) < 0,不一定是因为他们不知道优先规则。这样他们就更清楚了。

于 2010-08-27T13:28:30.483 回答
1

我投票支持快乐的媒介。我将使用的规则是在内容为多行时使用括号关键字。在行动:

// clear and succinct
with myGrid do begin
  for currRow := FixedRows to RowCount - 1 do begin
    if RowChanged(currRow) then begin
      if not(RecordExists(currRow))
        InsertNewRecord(currRow);
      else
        UpdateExistingRecord(currRow);
    end;  // if RowChanged
  end;  // next currRow
end;  // with myGrid
于 2010-08-27T13:36:38.830 回答
0

注释结尾对于类 html 语言非常有用,因此格式错误的 C 代码(如 if/else/if/else 的无限连续)也是如此

于 2009-07-21T18:54:32.693 回答
0

// 代码行末尾的频繁注释(根据您的良好行为和详细示例)使代码更难阅读恕我直言 - 当我看到它时,我最终会扫描“明显”的注释形成一些通常不存在的特殊内容.

我更喜欢仅在不明显的地方发表评论(即整体和/或独特的功能)

于 2009-07-21T18:55:16.513 回答
0

就我个人而言,我建议始终在支持它们的语言中使用块标识符(但要遵循您公司的编码标准,正如@Muad'Dib 建议的那样)。

原因是,在非 Python 语言中,空格(通常)对编译器没有意义,但对人类来说却是有意义的。

所以

with myGrid do
  for currRow := FixedRows to RowCount - 1 do
    if RowChanged(currRow) then
      Log(currRow);
      if not(RecordExists(currRow)) then
        InsertNewRecord(currRow)
      else
        UpdateExistingRecord(currRow);            

似乎做一件事,但做的事情却截然不同。

不过,我会消除行尾注释。使用突出显示块的 IDE。我认为Castalia会为 Delphi 做到这一点。您多久阅读一次代码打印输出?

于 2010-10-26T01:24:58.817 回答