Coding style 如果(条件)继续;或者如果(!条件){…}?(样式首选项)

Coding style 如果(条件)继续;或者如果(!条件){…}?(样式首选项),coding-style,Coding Style,我知道这是一个风格的问题,因此主观标签。我有一小段代码,带有两个嵌套条件。我可以用两种方式编写它,我想看看更有经验的开发人员认为它应该是什么样子 风格1: 风格2: (附带问题:如何在源代码示例中放置空行?我更喜欢样式1-带缩进。我更喜欢样式2-带continue语句。我肯定更喜欢第一个版本。continue语句在没有过度使用的情况下非常好 我会将其视为多个返回语句。它们对保护条款很有用,在提高清晰度时也很有用,但不应过度使用 此外,一行中的两个空格应该在代码块中插入换行符。我发现continu

我知道这是一个风格的问题,因此主观标签。我有一小段代码,带有两个嵌套条件。我可以用两种方式编写它,我想看看更有经验的开发人员认为它应该是什么样子

风格1:

风格2:


(附带问题:如何在源代码示例中放置空行?

我更喜欢样式1-带缩进。

我更喜欢样式2-带continue语句。

我肯定更喜欢第一个版本。
continue
语句在没有过度使用的情况下非常好

我会将其视为多个返回语句。它们对保护条款很有用,在提高清晰度时也很有用,但不应过度使用


此外,一行中的两个空格应该在代码块中插入换行符。

我发现continue语句使代码更难理解(因此也更难调试)。在某些情况下,您可能会使用它们,但我认为您的示例不属于这些情况。

尽可能避免
继续
语句


我们尽可能避免
goto
,不是吗?避免它的表兄
继续
难道不是也有意义吗?

我更喜欢带有缩进的样式1,它更干净,更容易理解,只要看一下就可以看到代码的布局。

在所示的示例中,我选择样式1。如果我的方法足够大,嵌套成为一个问题(而且没有更好的方法来重构代码),那么我会考虑样式2。但对于所示的两个紧凑型机箱,肯定是样式1。

我更喜欢样式2。此外,Refactoring.com上也描述了相同的示例

我认为,风格1更清晰。不反对Continue本身,但正如人们前面所说的,缩进便于后续操作。

第一种样式当然更清楚——它表示您(显然)的意思,即,获取消息,如果设置了
parseMsg
标志,则尝试解析它;如果成功的话,处理它。另一方面,第二个版本将处理更少的指令,特别是如果设置了
parseMsg
。我很想在两者之间折衷一下:

while (!String.IsNullOrEmpty(msg = reader.readMsg())){
    RaiseMessageReceived();

    if (!parseMsg) continue ;

    ParsedMsg parsedMsg = parser.parseMsg(msg);
    RaiseMessageParsed();
    if (processMsg){
       process(parsedMsg);
       RaiseMessageProcessed();
    }
}

…理论上,在关闭解析的特殊情况下,您将跳过所有解析。

我更喜欢样式1,并将continue语句等同于goto语句。我承认它在执行过程中可能不如另一个有效,但我发现代码理解效率几乎总是比代码执行效率更重要

这两个都是假的。不要将赋值放在条件表达式中

(!String.IsNullOrEmpty(msg = reader.readMsg()))
你这样做仅仅是因为读者的质疑行为——为什么读者会给你一条非消息来表示阅读已经完成?这里有一个设计更好的阅读器:

while (reader.HasMessage())
{
  string msg = reader.GetMessage();
  HandleMessage(msg);
}

原则上,我同意大多数人喜欢样式1。这就是Steve Mcconnell在“代码完成”中所支持的内容——说出你的意思,即如果你对条件为真更感兴趣,而错误状态更为罕见或不受欢迎,那么就说明首选版本


但在实践中,我发现自己经常使用Style2,因为我喜欢首先剔除所有可能的错误/无效状态。在我排除了所有我不感兴趣的可能性之后,我可以把核心代码写下来,直到例行程序结束,而不必不断地怀疑是否需要防范某些情况。基本上,我的态度是,去掉杂碎,然后平静地做真正的工作。

我个人更喜欢风格2,原因有很多

  • 您可能会遇到一个潜在错误,即在if之后缩进,但忘记了大括号

  • 您遇到浮动else问题的风险较小,即使用多个嵌套ifs时,您可能会混淆给定else属于哪个ifs

  • 您可以避免过度缩进,这会导致代码脱离页面

当我编写代码时,我倾向于将continue放在一个单独的行上

if (!parseMsg) 
    continue;

因为它使它更可见,并且更容易为它指定断点。

在担心表面上的不相关之前,我将不再使用全局变量在函数之间进行通信。您的语言可能支持函数返回值。使用这些

  • 表示每个步骤的成功或失败,或
  • 让每个转换函数返回下一个状态

哪一个更清楚

虽然我更喜欢样式1。我发现有时使用样式2很有用,因为它有助于降低缩进级别,并使代码更易于阅读


老实说,这两种风格都很好,这完全取决于个人的选择。

我的偏好是风格1,但如果有必要,我会立即使用风格2!parseMsg或!这种情况经常发生。始终将最有可能的情况放在第一位-正确吗?

Guard子句对于条件函数返回非常有效,因为它创建了一个完整的语句。你一眼就知道发生了什么事(我们到此为止)

continue语句通常需要更多的思考。我个人觉得如果你在循环中使用多个continue语句,你就做错了


我认为第一种类型是自我记录和标准方式。当你违反标准的方式时,你需要添加评论

我觉得样式1更容易遵循。所以我更喜欢样式1。

样式2让人类读者专注于重要的代码,甚至不去看任何不相关的东西——你可以看到continue语句,下面的任何东西都是不相关的


样式2管理复杂性并因此扩展到更复杂的方法,样式1很快变得难以管理的复杂

我想以不同的方向重构这段代码。您的代码正在对
while (reader.HasMessage())
{
  string msg = reader.GetMessage();
  HandleMessage(msg);
}
if (!parseMsg) 
    continue;