安卓标准括号风格的合法性

5
阅读这篇文章,它指出:
我们要求在条件语句的语句周围加上大括号。但是,如果整个条件语句(条件和主体)适合一行,则可以(但不必)将其全部放在一行上。也就是说,以下写法是合法的:
if (condition) {
    body(); 
}

这是合法的:
if (condition) body();

但这仍然是非法的
if (condition)
    body();  // bad!

为什么最后一种方式不好?它是前两种方式的混合,但为什么使用这种风格?在我看来,它是最易读的(或与第一种方式同样易读)。我知道这可能不仅适用于Android,但这是我第一次听说它。
6个回答

10

在你的代码中,存在一种不好的风格,即在使用不使用缩进来决定如何处理代码的语言中,你可能会遇到问题。想象一下,我正在维护你的代码,并看到了这个:

if (condition)
    body();  // bad!

我决定添加一行内容,使它变成这样:

if (condition)
    body();  // bad!
    myconditionalfcn(); // Will always execute
其他两种样式可以避免这个错误,一种是将整个条件放在单行中,另一种是确保我将新函数输入花括号中。
在修改别人的项目时,不应该打破他们的代码风格。在自己的项目中,应该在代码风格上追求可读性--第二种方式会导致像上面那样的混淆,影响可读性。好的编辑器可以自动纠正这个错误,但最好还是避免出现单行条件语句被分割的情况。

实际上,if(condition) body(); myconditionalfcn();(全部在一行)同样糟糕。一个真正健壮的编码风格要求在每个代码块上都加上花括号。 - Edwin Buck
@Edwin 我不反对;使用单行条件语句可能会带来问题。但是,在同一行写两个语句仍然是一个不同的风格问题。如果您的语句始终在单独的行上,单行条件很少会引起可读性问题,而断开的条件经常会在以后引起问题。我不同意你说一行代码和多行代码一样糟糕的说法。 - Dylnuge
@Edwin 我很困惑——我们什么时候开始讨论编译器了?当然,编译器不关心编码风格;那不是编码风格的相关内容。按照这个逻辑,我可以把所有的代码都写在一行上——毕竟,对于编译器来说它们都是一样的。而且,编码风格通常是一个主观的问题。 - Dylnuge
@Edwin 那完全不是一回事。编译器强制执行语法,而不是风格,你的故事是演变语法的例子,而不是演变风格(尽管我承认两者之间的界限模糊——例如,在Java中的空格是一种风格问题,但在Python中则是一种语法问题)。同样,即使所有人都认为将所有代码放在一行上是可怕的风格,编译器也不会阻止我这样做。 - Dylnuge
@Edwin 在另一种语言中,是的。不是在Java中。因此,编译器不会像未来的语言那样发展。再次问一下,我们是怎么谈到编译器以及它们如何处理代码的?你提出了这个问题,但我仍然不知道为什么/从哪里开始。 - Dylnuge
显示剩余5条评论

3

这并不特别适用于Android。像所有缩进问题一样,这是一个品味问题。无论如何,可以使用:

if (condition)
    body();  // bad!

第一种写法更好,因为第二种写法可能会让快速阅读代码的人感到困惑,因为不清楚条件语句何时结束。

if (condition) {
    body(); 
}

基于以下原因:
  1. 它完全没有歧义
  2. 如今的IDE(如Eclipse)使用自动补全功能,编写速度更快
  3. 在括号内添加其他语句更快,并且经常需要这样做。

虽然我同意倒数第三个观点,但一个人可能有多快地阅读代码并且没有看到if语句下面的单次执行取决于评估(假设使用正确的缩进风格)? - whirlwin
@Whirlin:@Dylnuge的回答恰好展示了我想说的。无论如何,在不使用括号的情况下使用条件语句并非错误,只是个人口味问题,就像我之前所说的那样。 - Heisenbug

3
编码风格是指导方针,合法的内容是语言定义所允许的。当他们在编码风格中使用“合法”一词时,只是指他们所接受的内容。例如:
if (condition)
  body();

这里特别指出的是缩进与执行混淆的问题,这实际上不是Java语言规范的一部分。换句话说,有人可能会看到

if (condition)
  statement1();
  statement2();

有些人可能会认为只有在条件成立时才会执行语句1和语句2。请注意,这种想法是错误的;良好的编码风格应该尽量减少其他人可能会犯的心理错误。

是否允许这样做是一个争议点。

if (condition) statement1();

是否应该加空格存在争议。对于许多人来说,这是可以接受的;然而,它实际上面临与上述示例相同的问题。Java不会根据空格的类型或数量做决策,它只会根据任何空格的存在做出决策。换句话说,您可能会通过这种方式使某人困惑。

if (condition) statement1(); statement2();

where语句2总是被执行;希望让他们混淆,认为语句2的执行与条件有关。这样做的原因是

if (condition) statement1();

通常认为这与极其罕见的看到类似语句的做法有很大关系。
if (condition) statement1(); statement2();

但接受非花括号版本并不意味着真正提高代码质量,有时候只是被接受是因为一般人不会写混乱的"all-in-one-line" if语句。

对于if语句,确保人们不会将行为与空格相关联的唯一安全方法是始终插入花括号。

if (condition) { statement1(); } statement2();

这段代码看起来有些奇怪,但它可以提供足够的视觉线索,以防止人们错误地认为语句2的执行取决于语句1。

最后,

if (condition) {
  statement1();
}
statement2();

永远不会让任何人感到困惑。唯一可能的代价是存储一些额外的空格字符和添加几条水平输入线。考虑到有多少存储空间可用,我认为存储论点已经死了。屏幕房地产论点仍然存在;但是,有时为了清晰表达一个想法,值得在屏幕上多加几行(而且现在的屏幕比过去大得多)。当考虑到由于阅读代码时的“心理错误”而在追求“错误思路”时浪费的人力成本时,似乎在这里或那里多加一些花括号可以很好地为自己付出。
此外,如果您连续使用大量的if语句,最好使用switch或多态。

好的阅读,但是看着你的第二段代码,我认为实际问题在于缩进而不是缺少花括号。 - whirlwin
@Whirlwin 缩进问题源于一开始允许缺少大括号 - 关键是有人可能会因为错误而很容易地添加这个,尤其是在代码库中既包含像Python这样的基于空格分隔的语言,又包含像Java这样的非空格分隔语言。包括大括号或使用单行代码可以消除意外添加另一行并认为它执行的可能性。正如Edwin所说,“良好的编码风格试图最小化可能发生的心理错误数量。” - Dylnuge
@Whirlwin,Java语言规范对缩进没有任何明确的说明。因此,从语言的角度来看,缩进是不存在的。人们使用缩进以一种编译器不处理的方式“注释”他们的语言。因此,如果您错误地注释,就像在注释中陈述虚假信息一样。它只会误导阅读代码的人。由于花括号被编译器视为关键符号,因此不可能误导其含义,否则会生成编译器错误。请注意,这并不适用于具有空格编译器规则的语言,例如Python。 - Edwin Buck

1

在我看来,当谈到代码格式时,不能使用“合法”和“非法”等词语。在我的理解中,“非法”是指对应用程序有害的东西。正确或错误的格式化不会导致程序失败,格式化只是一种使代码易读的方式。如果你在团队中工作,你应该考虑使用正确的格式化方式让你的队友们理解你的代码。当你独自工作时,这并不重要,你可以按照自己的格式化风格编写任何你喜欢的内容。这只是我的观点。

P.S. 我个人只使用第一种样式,它有助于防止愚蠢的错误。


1
如果他们强制执行一个开源项目的编码标准,那就存在“合法”或“不合法”的问题,因为该项目得到了数千名开发人员的贡献。请仔细阅读OP所链接的文章,至少是标题部分。它说:“贡献者的代码风格指南”。 - Pedantic
我认为它是合法/非法的,根据最佳实践,而不是实际代码本身。 - whirlwin
这篇文章不是关于“最佳实践”,而是关于代码风格,这些风格将被他们的项目拒绝。合法=被上游接受,非法=被拒绝。 - Pedantic
@Chris,谢谢。我已经相应地更新了问题的标题。 - whirlwin

0

为了可读性,我更喜欢

if (conditiontest) doOneThing();

在这两者之间

if (conditiontest) { doOneThing(); }

if (conditiontest) {
     doOneThing();  }

if (conditiontest) { 
     doOneThing(); 
     }

这只是我的个人观点。但我认为它增强了简洁性。

0

个人代码风格偏好与严格遵守风格标准相结合,为项目作出贡献。

如果您对提交任何代码到AOSP都没有兴趣,那么不必太担心。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接