【问题标题】:Should indentation always be minimized? [closed]是否应该始终最小化缩进? [关闭]
【发布时间】:2015-01-19 09:34:56
【问题描述】:

我想听听您对最小化缩进是否好的意见。

我通常是这样处理问题的:

int foo_a() {
    if (!check_value(x)) {
        // error
        return false;
    }
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    return true;
}

另一方面,我也看到了这样的代码:

int foo_b() {
    if (!check_value(x)) {
        // error
        return false;
    } else {
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        return true;
    }
}

int foo_c() {
    if (check_value(x)) {
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        return true;
    } else {
        // error
        return false;
    }
}

但这可能适得其反,因为如果每一次检查都会创建一个新的 else-branch,则 ident 会变得非常大。

另一方面,对于决策,例如蔬菜或肉类,我通常这样做:

int foo_d(FOOD food) {
    if (food.isVegetable) {
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        return;
    } else {
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        return;
    }
    // assume here is NO shared code which is always executed for both food types.
}

但是像 foo_a() 那样做,它应该是这样的:

int foo_e(FOOD food) {
    if (food.isVegetable) {
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        // do stuff
        return;
    }

    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    // do stuff
    return;
}

【问题讨论】:

  • 这不是关于意图,而是关于多个返回语句、错误检查和(不必要的)else 子句。
  • 不一定需要有返回值。问题是,我应该在哪里使用“else”以获得良好的编码风格,以及在哪里只有一个“if”并在其末尾返回(返回有或没有值)。
  • 这就是我所说的,这与意图无关(而且我没有在任何地方提到返回值)。所以 - 在我看来 - 你应该改写你的问题和标题。
  • 我将删除我的答案,我对所问的内容感到困惑:P

标签: coding-style indentation conventions


【解决方案1】:

我个人认为两者都

if(flag) {
    //long computation
    return;
} else {
    //long computation
    return;
}

还有

if(flag) {
    //long computation
    return;
}
//long computation
return;

是反模式,因为它们使推理程序流程和可能的返回值变得更加困难。它们也更有可能在重构期间导致错误 - 或者通常在后期修改期间,因为人们可能会忽略第一个 return 语句。

因此,一些编码指南只允许每个函数使用一个返回语句。在这种情况下,您将始终必须使用 if 和 else:

int foo(int param) {
    int retval = 0;
    if (param > 0) {
        //computation
        retval = 5;
    } else {
        //computation
        retval = -1;
    }
    return retval;
} 

我个人通常允许两个允许返回语句的区域: 在异常或微不足道的返回开始处(例如,foo_a() -example 中的参数检查)和最后返回常规返回值的地方。请注意,这两个区域都可以有多个 return 语句,尽管我的函数很少有多个“常规”退出点。

int foo2(int param1, int param2) {
    if (!precondition1(param1)) return -1;//error
    if (!precondition2(param2)) return -2;//error
    if (param1==param2) return 0; // no error, but answer can be determined trivially       

    //computation

    return local_variable; //return regular result
}

这里开头的前两个返回语句也可能是断言或异常。

如果我根据标志或参数的值(如food.isVegetable)进行两种不同的计算,我总是使用 if-else 并在两者之后使用单个 return 语句,如上面的第一个示例所示。

此外,如果意图级别变得太高,您可能需要考虑编写一个单独的函数。这并不总是可能的,但比您想象的更常见。例如。对于错误检查,您可以围绕检查错误输入的实际函数编写一个包装器:

int fooChecked(int param) {
    int retVal;
    if (param > 0 && param < 200) {
        retval = foo(param);
    } else {
        retVal = -1;            
    }
    return retVal;
}

【讨论】:

    【解决方案2】:

    这只是风格问题,但我会选择代码更少,缩进更少的方式。

    如果您通过提取函数来保持函数简短,则无论您选择哪种方式,它都应该保持可读性。例如:

    int foo_e(FOOD food) {
        if (food.isVegetable)
            return foo_vegetable(food);
    
        return foo_meat(food);
    }
    

    【讨论】:

    • 另一方面,您认为什么更重要,代码的可读性和大小,或者避免意外错误导致问题,最坏情况下的安全漏洞?例如,如果“vegetable”分支中的 return 意外被删除或忘记,则“meat”分支将被执行,如果使用了“else”则不会出现这种情况。
    • 根据我的经验,提高可读性几乎总是会减少意外错误的机会。老实说,您应该致力于使用 OOP、多态性和策略和抽象工厂等设计模式来最小化这些类型的 if。
    猜你喜欢
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多