是否有必要在每个 if 条件中写 else 部分?

Posted

技术标签:

【中文标题】是否有必要在每个 if 条件中写 else 部分?【英文标题】:Is it necessary to write else part in every if condition? 【发布时间】:2011-03-24 13:30:05 【问题描述】:

我问的问题可能已经结束,但我只想知道是否有必要在每个 if 条件中编写 else 部分。我的一位高级程序员对我说“你应该在每个 if 条件中写 else 部分”。假设我们没有在 else 部分写的条件,那我们该怎么办?我认为这里将进行健康的讨论....

【问题讨论】:

我尽量不要“应该”在我的同龄人身上。它往往会变得混乱。仅在有意义时才使用 else。 “如果”你总是听你的同事的话,你就会养成他们的坏习惯。没有必要说“'else' 你可以自己学习”。 我认为您的高级程序员实际上说过,“您应该考虑每个 if 条件中的 else 部分”。由于缺少 else 块,我已经看到太多代码失败了。 似乎这是一个更好的答案:***.com/questions/35053371/… Kubernetes 称之为“航天飞机风格”,它用于帮助确保正确性 - 值得一读:github.com/kubernetes/kubernetes/blob/… 【参考方案1】:

这是一个可怕的想法。你最终得到以下形式的代码:

if (something) 
    doSomething();
 else 

我怎么会认为根本没有else 更具可读性或可维护性。这听起来像是那些有太多空闲时间的人制定的规则之一。尽快让他们开除,或者至少冷静而安静地离开:-)

【讨论】:

"One option is to code the else clause—with a null statement if necessary—to show that the else case has been considered. Coding null elses just to show that that case has been considered might be overkill, but at the very least, take the else case into account. When you have an if test without an else, unless the reason is obvious, use comments to explain why the else clause isn’t necessary." - Code Complete我觉得很矛盾,你怎么看? 我认为,就像那本书中引用的很多东西一样,它需要在 context: 中,前面的句子是:“如果你认为你需要一个普通的if声明,考虑您是否真的不需要if-then-else 声明。” 我编写的每一段代码都是经过深思熟虑的结果:nn 这个案例被拒绝了,因为一个体面的程序员会知道缺少else 子句意味着没有操作应采取。我没有读过函数并且想知道从未放在它末尾的七行,这正是你应该对丢失的else 采取的态度:-) 这本好书的问题在于它时不时地做出非常明显/初学者的陈述。例如,在前一页中,它说you should avoid 'if-then-else' statements where the 'if' block has no statements in its body and instead negate the test condition(我在解释)。 虽然我不是在抱怨。在任何一天,我都会选择一本对包含神秘晦涩内容的书做出明显陈述的书,因为作者在明显/不明显(首先这可能永远不可能,因为每个人都有不同的知识/经验)之间划清界限)错误的地方。【参考方案2】:

不,您当然没有必须 - 至少在大多数语言中是这样。 (您没有指定;很可能有一种语言确实强制执行此操作。)这是一个我肯定不会执行的示例:

public void DoSomething(string text)

    if (text == null)
    
        throw new ArgumentNullException("text");
    
    // Do stuff

现在您可以在此处将方法的主要工作放入“else”子句中 - 但它会不必要地增加嵌套。再添加几个条件,整个事情就变得一团糟。

根据我的经验,这种“提前退出”模式相当普遍 - 并且适用于返回值和异常。我知道有些人喜欢方法中的单个返回点,但在我使用的语言(Java、C#)中,这通常会导致代码的可读性显着降低和嵌套更深。

现在,有一种情况有更大的争论空间,那就是两个分支都是终端,但它们都不是有效的捷径:

public int DoSomething()

    // Do some work
    if (conditionBasedOnPreviousWork)
    
        log.Info("Condition met; returning discount");
        return discount;
    
    else
    
        log.Info("Condition not met; returning original price");
        return originalPrice;
    

(请注意,我故意让两个分支都做更多的工作,而不是仅仅返回 - 否则条件语句将是合适的。)

如果没有“else”,这会更具可读性吗?这真的是个人选择的问题,我不会声称我总是一致的。让两个分支同样缩进以某种方式赋予它们相同的权重 - 并且可能通过颠倒条件来鼓励以后重构的可能性......而如果我们刚刚降到“返回原始价格”,那么将 放入的重构 if 块并将折扣情况 移出 if 块乍一看不太明显。

【讨论】:

【参考方案3】:

在 Java 和 C 等命令式语言中,if - else 是一个语句,不返回值。所以你可以愉快地只写if 部分并继续。而且我认为这是更好的做法,而不是在每个 if 之后添加空的 elses。

但是在 Haskell 和 Clojure 等函数式语言中,if 是一个表达式,它必须返回一个值。所以它必须以else 成功。但是,仍然存在您可能不需要else 部分的情况。对于这种情况,Clojure 有一个 when 宏,它包装 if - else 以在 else 部分返回 nil 并避免编写它。

(when (met? somecondition)
  (dosomething))

【讨论】:

+1 是唯一提及if-else 表达式的答案。【参考方案4】:

危险!危险,威尔罗宾逊!

http://en.wikipedia.org/wiki/Cargo_cult_programming

包含空的else 块是否会以某种方式提高代码的质量、可读性或健壮性?我认为不会。

【讨论】:

【参考方案5】:

纯粹从语义的角度来看 - 我想不出一个案例 每个 if 都没有隐含的 else。

如果在我到达墙壁之前没有停下车,我会撞车,否则我不会撞车。

除了语义:

这个问题的答案取决于环境,以及错误的结果。

企业代码?按照您的编码标准执行。 恕我直言,您会发现,虽然最初看起来工作量太大,但当您重新访问该代码时,将在 10 年后变得非常宝贵。但是,如果你错过了一个重要的“反条件”,那肯定不会是世界末日。

但是:安全、安全或生命关键代码?那是一个不同的故事。

在这种情况下,您想做两件事。 第一:不是测试故障,而是要证明有故障。这需要对进入任何模块持悲观态度。你认为一切都是错的 直到你证明它是正确的。 第二:在生命中至关重要:你永远不想伤害病人。:

bool everyThingIsSafe = true;
if(darnThereIsAProblem())

   reportToUserEndOfWorld();

return everyThingIsSafe;

哎呀。我忘记将everyThingIsSafe 设置为false。 调用此代码段的例程现在被骗了。如果我将 evertThingIsSafe 初始化为 false - 我总是安全的,但现在我需要 else 子句来表明没有错误。 是的,我本可以将其更改为阳性测试 - 但我需要 else 处理故障。 是的,我本可以为everyThingIsSafe() 分配支票的立即返还。 然后测试标志以报告问题。一个隐含的 else,为什么不显式呢? 严格来说,this所代表的隐含else是合理的。 对于 FDA/安全审核员,也许不是。 如果它是明确的,可以指向测试,它的其他,并且我清楚地处理了这两个条件。

我从事医疗设备编码已有 25 年了。在这种情况下,您需要 else,您需要 case 中的默认值,并且它们永远不会为空。你想确切地知道会发生什么,或者尽可能接近。因为忽略一个条件可能会杀死一个人。

查找 Therac-25。 8人重伤。 3死。

【讨论】:

【参考方案6】:

我知道我迟到了,但我对此做了很多思考并想分享我的结果。

在关键代码中,必须考虑每个分支。写一个else不是必须的,但要留下一个标记else是没有必要的以及为什么。这将有助于审稿人。观察:

//negatives should be fixed
if(a < 0) 
    a+=m;

//else value is positive

【讨论】:

【参考方案7】:

不,不需要为if 语句编写else 部分。

事实上,大多数开发人员更喜欢并建议避免使用 else 块。

那是

而不是写

if (number >= 18) 
    let allow_user = true;
 else 
    let allow_user = false;

大多数开发人员更喜欢:

let allow_user = false;
if (number >= 18) 
    let allow_user = true;

【讨论】:

【参考方案8】:

有时没有其他部分......并且包括一个空的部分只会使代码的可读性降低恕我直言。

【讨论】:

【参考方案9】:

不,你不必..

另外,我认为这对于可读性来说不是一个好主意,因为你会有很多空的 else 块。这不会很漂亮。

【讨论】:

【参考方案10】:

这纯粹是风格和清晰度的问题。很容易想象 if 语句,特别是简单的语句,else 将是多余的。但是当你有一个更复杂的条件时,也许要处理许多不同的情况,通常可以明确地明确声明,否则,什么都不应该做。在这些情况下,我会在其他为空的 else 中留下 // do nothing 评论,以明确该空间是故意留空的。

【讨论】:

【参考方案11】:

不,但我个人选择始终包含封装括号以避免

if (someCondition)
    bar();
    notbar();  //won't be run conditionally, though it looks like it might

foo();

我会写

 if (someCondition)
        bar();
        notbar();  //will be run
 
 foo();

【讨论】:

我的规则是内联(在一行)ifs不需要大括号,但如果语句的内容在另一行,那么大括号是必要的。【参考方案12】:
def in_num(num):
    if num % 3 == 0:
        print("fizz")
    if num % 5 == 0:
        print("buzz")
    if (num % 3 !=0) and (num % 5 !=0):
        print(num)

在此代码中查看 else 语句是不必要的。

【讨论】:

这是一个没有必要的问题。

以上是关于是否有必要在每个 if 条件中写 else 部分?的主要内容,如果未能解决你的问题,请参考以下文章

#if, #elif, #else, #endif 使用

Go if else

条件语句在 if-else-if 阶梯的两个部分都为真

oracle存储过程中写IF ELES

if-else 语句

[07 Go语言基础-if-else]