如何在 if 语句块中去除否定?

huangapple go评论69阅读模式
英文:

How to remove negation in if block?

问题

按照推荐的做法,使用do..while模式的代码如下:

for {
    work()
    if !condition {
        break
    }
}

下面的代码使用for循环实现了do..while(condition):

var r *s
var err error
counter := 0

for { // do..while(specificerror && < MAX && trigger_not_initiated)

    r, err = f()
    counter = counter + 1
    if !(err != nil &&
        strings.Contains(err.Error(), "specificerror") &&
        counter < MAX &&
        !IsTriggerInitiated()) {
        break
    }
}

但是审查团队建议在if语句中通过移除negation(condition)来使条件更易读。

如何移除if语句中的negation in negation(condition)呢?

英文:

Followed the do..while pattern recommended here:

for {
    work()
    if !condition {
        break
    }
}

Below code is implementing do..while(condition) using for loop:

var r *s
var err error
counter := 0

for { // do..while(specificerror &amp;&amp; &lt; MAX &amp;&amp; trigger_not_initiated)

    r, err = f()
    counter = counter + 1
    if !(err != nil &amp;&amp;
        strings.Contains(err.Error(), &quot;specificerror&quot;) &amp;&amp;
        counter &lt; MAX &amp;&amp;
        !IsTriggerInitiated()) {
        break
    }
}

But review team suggests to make if condition more readable by removing negation in negation(condition) in if statement

How to remove negation in negation(condition) for if statement?

答案1

得分: 7

你需要的转换被称为德摩根定律:

  • 非 (A 或 B) = (非 A) 且 (非 B)
  • 非 (A 且 B) = (非 A) 或 (非 B)

所以如果你有一个像这样的语句:

if !(a && b && c) {}

它等价于

if !a || !b || !c {}

在你的例子中:

if !(err != nil &&
    strings.Contains(err.Error(), "specificerror") &&
    counter < MAX &&
    !IsTriggerInitiated()) {
    break
}

翻译后的版本:

if err == nil ||
    !strings.Contains(err.Error(), "specificerror") ||
    counter >= MAX ||
    IsTriggerInitiated() {
    break
}

需要检查的一件事是:短路求值。在一系列的 && 中,如果一个表达式求值为 false,那么剩下的表达式将不会被求值(我们知道结果是 false)。

幸运的是,在翻译后的版本中,这一点将保持不变:短路求值将保持相同,因为在一系列的 || 中,如果一个表达式求值为 true,那么剩下的表达式将不会被求值(我们知道结果是 true)。因此,当原始形式中的 afalse 时,在转换后的形式中 !a 就是 true

英文:

The transformation you need is called De Morgan's Laws:

> - not (A or B) = (not A) and (not B)
> - not (A and B) = (not A) or (not B),

So if you have a statement like this:

if !(a &amp;&amp; b &amp;&amp; c) {}

It is equivalent to

if !a || !b || !c {}

In your example:

if !(err != nil &amp;&amp;
    strings.Contains(err.Error(), &quot;specificerror&quot;) &amp;&amp;
    counter &lt; MAX &amp;&amp;
    !IsTriggerInitiated()) {
    break
}

Translated version:

if err == nil ||
    !strings.Contains(err.Error(), &quot;specificerror&quot;) ||
    counter &gt;= MAX ||
    IsTriggerInitiated() {
    break
}

One thing that needs to be inspected: short-circuit evaluation. In a series of &amp;&amp; if an expression is evaluated to false, the rest will not be evaluated (we know the result is false).

Luckily, this will remain the same in the translated version: short-circuit evaluation will be the same, because in a series of || if an expression is evaluated to true, the rest will not be evaluated (we know the result is true). So when in the original form a is false, that's exactly the same case when !a is true in the transformed form.

答案2

得分: 4

如何在if语句中移除否定条件中的否定?

按照建议,可以使用"||"来实现。

if !(a && b)

等同于

if !a || !b

更多信息,请参考德摩根定律

英文:

> How to remove negation in negation(condition) for if statement?

Exactly as suggested ("use ||")

if !(a &amp;&amp; b) 

is equivalent to

if !a || !b

For more information, see De Morgan's laws.

huangapple
  • 本文由 发表于 2021年10月21日 18:39:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/69660427.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定