为啥 switch 语句上有奇怪的缩进?

Posted

技术标签:

【中文标题】为啥 switch 语句上有奇怪的缩进?【英文标题】:Why the strange indentation on switch statements?为什么 switch 语句上有奇怪的缩进? 【发布时间】:2011-05-29 09:15:07 【问题描述】:

为什么“case”的imho缺少缩进-switch语句中的关键字被认为是好的样式?

“case”关键字的不缩进似乎是几乎每个 IDE 中的默认格式选项:

switch (i)
case 0:
    break;
case 1:
    break;

虽然我觉得这种格式更直观:

switch (i)
    case 0:
        break;
    case 1:
        break;

这背后有什么逻辑让我无法理解吗?

【问题讨论】:

直到现在才意识到这一点!可能是因为 switch 是在缩进之前发明的)) NB 默认缩进 switch (而且它看起来对我来说也更具可读性) Why don't people indent C++ access specifiers/case statements?的可能重复 官方文档不遵循代码约定:docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.htmldocs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.11 @g*** IDEA 15.0.5 它不适合我。我希望它做到了。我更喜欢缩进来对应逻辑分组,而开关是一个逻辑元素,人们通常希望将其效果视为一个单元。因此,我想将其视为一个单元(例如缩进)。我也倾向于在 case 部分的语句周围添加大括号。 【参考方案1】:

FWIW,另一种选择是使用两个半缩进:

switch (i) 
  case 1:
    ...
  case n:
    ...

【讨论】:

【参考方案2】:

1999 年的官方 Oracle Code Conventions for the Java TM Programming Language(第 7.8 节)推荐一种 switch 样式,其中 case 语句相对于整个 switch 语句不缩进。

这是一个主观的选择,但孙认为最好每个人都坚持一种风格,并选择了这个。

【讨论】:

嗯。祝你好运!【参考方案3】:

四个字:无块,无缩进

案例没有打开一个块。在 C 或 C++ 中,您甚至可以在 switch 块的开头放置变量声明(但不调用初始化程序,静态变量除外,这是一个陷阱)。你可以用switch 做很多奇怪的事情,比如Duff's device。

因此,由于大小写只是标签,缩进它们似乎并不直观,而且不缩进是大多数样式选择的样式。

【讨论】:

我不会说它们一定是标签,因为您可以将它们视为标签和if-elses 序列的语法糖。不过,既然它们看起来像标签,那么缩进可能更合适。 我不认为该规则描述了有问题的样式。 switch 确实引入了一个块,而 case 没有。然而case 似乎引入了新的缩进级别,而switch 没有。 @rodion:就复杂性而言,C 开关实现是 O(1),等效的 if-else 字符串是 O(n)。 if-else 期望后面紧跟一个语句,而不是 case 等。您还可以在 C 标准中找到对 case 的引用作为标签(没有检查确切的报价,但我很确定我已经看到了)。 @Steve: switch 本身不会引入块。它只是人们通常用作引入块的依赖语句的块语句。 @kriss:所有自动变量声明都是定义。他们只是没有初始化。将初始化的变量定义放在开关的开头没有什么坏处,但是初始化永远不会执行,所以没用。当然,静态变量定义在 switch 开始时也是有效的,无论它们是否被初始化。【参考方案4】:

也许是为了保持与if 语句中表达的逻辑等价物相同的缩进级别?那就是:

switch(i)
case 0:
  //do something 1
case 1:
  //do something 2

看起来类似于它的逻辑等价物:

if(i==0)
  //do something 1
else if(i==1)
  //do something 2

【讨论】:

可能不会 - 如果可能,switch/case 通常由跳转表实现,而不是 if/else 蛇。 这可能是唯一对我有意义的解释【参考方案5】:

有不同的缩进样式可供选择。 AFAIK,只要您始终使用缩进样式,就没有一种样式比其他样式更好。对我来说,缩进 case 标签更具可读性,privateprotectedpublic 标签在类中也是如此,但是,我的 IDE 不会按照我的方式缩进。我的代码不像我希望的那样可读。哦,好吧……

【讨论】:

对我来说也一样,我真的很讨厌没有缩进的案例,已经编程了 20 多年,但我也可以买它是一个主观问题......【参考方案6】:

案例在逻辑上是标签。许多人将标签放在与他们所在的块相同的缩进级别。在我看来,这样更容易阅读文本。

我将它与您可以滚动浏览的时间线进行比较。您在时间线本身上有标记,而不是缩进到内容中。然后,您可以快速指出标签/标记的位置,而无需将视线从基线上移开。

【讨论】:

换句话说,switch 块的内容比switch 本身缩进了一个级别,但是case s 比它们的代码“缩进”了一个级别'重新混合。 我对此持观望态度,倾向于缩进,因为我认为它更具可读性。这个答案以及防止过度缩进/包装的好处改变了我的看法。将 case 视为标签而不是 if 条件在不缩进时似乎有助于提高可读性。 case 部分的作用类似于标签,因为执行流程将通过标签从上面的代码继续到下面的代码,而没有break。我还是更喜欢看到它们缩进。在我看来,如果没有缩进,switch 语句本身就会隐藏起来,因此很难看到事情的开始。但这只是在案例太多时才是真正的问题,而这完全不是问题。 默认条款呢?在 Eclipse (Java) 中,开关的默认大小写会自动缩进,而不是像案例那样“未缩进”。我认为在默认情况下发生的事情的易读性等于在定义的情况下对可读性的需求。 如果你也有cases 的大括号怎么办?您最终会在不同的行上以相同的缩进级别得到 2 个右大括号。

以上是关于为啥 switch 语句上有奇怪的缩进?的主要内容,如果未能解决你的问题,请参考以下文章

PHPStorm switch语句'break'缩进

switch 究竟应该怎么缩进

switch语句括号中的东西为啥一定得是整型的?

ESlint: switch case缩进问题

为啥 switch 语句没有大括号?

这个PHP流程判断switch语句哪里出错了?为啥不执行default后面的语句