始终对条件和循环使用大括号……或不使用

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

这篇文章最初于 2013 年 9 月 25 日在程序员的牧场 发布。原始文章提到 jesse liberty 是“建议始终使用大括号的人之一”和条件语句。然而,jesse liberty 在阅读这篇文章后改变了他的观点(正如您在原始文章的评论中看到的那样)。因此,此处介绍的文章已略作编辑以删除此声明。

大家好!

在学习 jesse liberty 的一些 pluralsight 课程 (我强烈推荐)时,我想起了 关于在涉及控制流语句(条件和循环)时是否应该始终使用大括号的长期争论 。所以假设我们有以下条件:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

始终使用牙套 阵营的支持者会让我们这样写:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

在本文中,我将讨论这种方法的优点和缺点,以及根据我的经验提出的个人意见。我想从一开始就说这篇文章是主观的,并不完全是事实或客观的——所以就按它的本来面目吧。正是因为这是个人品味的问题,所以在这个问题上没有普遍的共识。

括号样式

大括号(或花括号)几乎是任何使用 c 风格语法的编程语言的一个特性,包括 c、c++、java、c#、javascript、php 和许多其他语言。他们定义了一个作用域块,可以作为控制流(条件和循环)的一部分作为单个语句执行。有许多不同的样式可以使用它们。

java 人似乎喜欢这种风格:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

另一方面,.net 阵营似乎更喜欢垂直对齐大括号:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

如果你只有一个语句,从技术上讲,你可以省去大括号,这样你就可以这样写你的代码:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

……或者像这样。


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

就个人而言,我认为第一个和最后一个选项在可读性方面并不是最好的(尤其是当代码变得复杂时),所以我将重点关注第二个和第三个。当我有多个语句时,我通常使用第二个选项(带大括号),而当我只有一个时,我通常使用第三个选项(没有大括号)。许多人建议始终使用大括号,并将第三种选择视为不好的做法。让我们来看看原因。

如果你需要添加语句,你会发现大括号已经准备好了

所以让我们举一个和以前一样的例子,你有这个声明:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

如果您需要添加额外的语句作为条件的一部分执行,无论如何都必须添加大括号。有些人建议始终使用大括号 ,以便在需要添加其他语句时发现大括号已准备就绪

在那种情况下,我想,我们不应该在 xml 中使用空元素语法:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

…而是总是完整地写下我们的标签:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

…仅仅是因为我们可能需要在某个时候在元素内添加一些东西。我认为这是一个非常薄弱的​​论点,因为它忽略了一种可能非常方便的语言特性,同时用一些对代码没有任何意义的东西使代码膨胀。看看本文中的前两个代码片段——使用大括号的代码片段的长度(就行数而言)是另一个代码片段的两倍。为了什么?因为人们懒得在最终需要时输入大括号? 扫管笏

添加语句可能容易出错

省略大括号被认为是不好的做法的另一个原因是,在维护此类代码时可能很容易引入逻辑错误(请参阅 程序员 stackexchange 上的这个问题 堆栈溢出上的另一个问题 )。假设你有这个:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

然后,您添加一个旨在在条件范围内的附加语句,您可以这样做:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

哎呀!第二个 console.writeline() 实际上不是条件的一部分,所以它总是被执行,无论如何。这是一个有效的论点。但让我们进一步剖析它。

首先,让我们从简单的单行条件语句重新开始:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

现在,如果你想在此时添加代码,你有两种做法。如果你想添加语句作为条件的一部分,你 知道 只有一个语句并且没有大括号,所以添加它们应该是一个非常自动的响应:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

另一方面,如果要添加 属于条件语句的语句,请将其添加到与 if 语句相同的级别:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

即使没有大括号,缩进也清楚地表明一个语句属于条件语句而另一个则不属于。所以实际上,当看到这种代码时:


 if (x == 0)
    console.writeline("x is zero");
else if (x < 0)
    console.writeline("x is negative");
else if (x > 0)
    console.writeline("x is positive");

…我忍不住认为可读性问题(导致不正确的控制流)是缩进问题之一,而不是是否使用大括号的问题。

我当然可以想象新手程序员会犯这种错误,但我很难相信经验丰富的程序员会发现很难阅读基本条件语句。作为 这个问题 的答案之一:

“我什至觉得这应该是一个常见的错误是难以置信的:块是编程的基本部分。块级解析和范围界定是程序员自动的、根深蒂固的心理过程。大脑就是这么做的(否则,关于编程的推理会困难得多)。记住放置大括号不需要额外的脑力劳动:毕竟,程序员还记得正确缩进新添加的语句;所以程序员已经在心理上处理过涉及到一个块。” — 康拉德·鲁道夫

此外, 本文 的其中一个部分指出:

“有足够纪律的程序员总是注意到大括号(并在需要时将它们放入)不需要这个习语 [总是使用大括号]。

“自动缩进编辑器使你的新语句是否是 else 子句的一部分变得显而易见,使你不太可能遇到这个习语试图防止的错误。”

概括

就个人而言,我认为在不需要时使用大括号是浪费空间,会导致很多不必要的代码行。我在需要时使用它们,并且不将它们用于单个语句。我发现在不需要时省略大括号没有错。这对我有用了很多年,你可能同意也可能不同意我的观点。不同的人发现自己喜欢使用不同的方法,并且对于什么是最好的并没有普遍的共识。

所以找出最适合你的方法,不要让任何人根据主观论据告诉你应该如何编写代码。虽然您绝对应该从更有经验的程序员那里学习基于理性和逻辑论证的最佳实践,但要务实并且不要对您的代码过于虔诚。