缩进应该总是最小化吗?
Should indentation always be minimized?
我想听听您对尽量减少缩进是否有益的看法。
我通常是这样处理问题的:
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 分支,idents 会变得非常大。
另一方面,对于决策,例如蔬菜或肉类,我通常这样做:
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;
}
这只是风格问题,但我会选择代码更少、缩进更少的方式。
如果您通过提取函数来保持函数简短,那么无论您选择什么,它都应该保持可读性。例如:
int foo_e(FOOD food) {
if (food.isVegetable)
return foo_vegetable(food);
return foo_meat(food);
}
我个人认为
if(flag) {
//long computation
return;
} else {
//long computation
return;
}
以及
if(flag) {
//long computation
return;
}
//long computation
return;
是反模式,因为它们使推断程序流和可能的 return 值变得更加困难。它们也更有可能在重构过程中导致错误 - 或者通常在以后的修改过程中,因为人们可能会忽略第一个 return 语句。
出于这个原因,一些编码指南只允许每个函数一个 return 语句。在这种情况下,您将始终必须使用 if
和 else
:
int foo(int param) {
int retval = 0;
if (param > 0) {
//computation
retval = 5;
} else {
//computation
retval = -1;
}
return retval;
}
我个人通常允许两个 areas 其中允许 return 语句:
就在异常或琐碎的 returns 的开头(例如 foo_a()
-示例中的参数检查)和最后,常规 return 值为 return编辑。请注意,在这两个区域中可以有多个 return 语句,尽管对于我的函数来说,具有多个 "regular" 退出点并不常见。
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
}
此处开头的前两个 return 语句也可能是断言或异常。
如果我根据标志或参数的值进行两种不同的计算(如 food.isVegetable
),我总是像第一个示例一样在两者之后使用 if-else 和单个 return 语句以上。
此外,如果意图级别变得太高,您可能需要考虑编写一个单独的函数。这并不总是可能的,但比您想象的更频繁。例如。对于错误检查,您可以围绕检查错误输入的实际函数编写一个包装器:
int fooChecked(int param) {
int retVal;
if (param > 0 && param < 200) {
retval = foo(param);
} else {
retVal = -1;
}
return retVal;
}
我想听听您对尽量减少缩进是否有益的看法。
我通常是这样处理问题的:
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 分支,idents 会变得非常大。
另一方面,对于决策,例如蔬菜或肉类,我通常这样做:
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;
}
这只是风格问题,但我会选择代码更少、缩进更少的方式。
如果您通过提取函数来保持函数简短,那么无论您选择什么,它都应该保持可读性。例如:
int foo_e(FOOD food) {
if (food.isVegetable)
return foo_vegetable(food);
return foo_meat(food);
}
我个人认为
if(flag) {
//long computation
return;
} else {
//long computation
return;
}
以及
if(flag) {
//long computation
return;
}
//long computation
return;
是反模式,因为它们使推断程序流和可能的 return 值变得更加困难。它们也更有可能在重构过程中导致错误 - 或者通常在以后的修改过程中,因为人们可能会忽略第一个 return 语句。
出于这个原因,一些编码指南只允许每个函数一个 return 语句。在这种情况下,您将始终必须使用 if
和 else
:
int foo(int param) {
int retval = 0;
if (param > 0) {
//computation
retval = 5;
} else {
//computation
retval = -1;
}
return retval;
}
我个人通常允许两个 areas 其中允许 return 语句:
就在异常或琐碎的 returns 的开头(例如 foo_a()
-示例中的参数检查)和最后,常规 return 值为 return编辑。请注意,在这两个区域中可以有多个 return 语句,尽管对于我的函数来说,具有多个 "regular" 退出点并不常见。
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
}
此处开头的前两个 return 语句也可能是断言或异常。
如果我根据标志或参数的值进行两种不同的计算(如 food.isVegetable
),我总是像第一个示例一样在两者之后使用 if-else 和单个 return 语句以上。
此外,如果意图级别变得太高,您可能需要考虑编写一个单独的函数。这并不总是可能的,但比您想象的更频繁。例如。对于错误检查,您可以围绕检查错误输入的实际函数编写一个包装器:
int fooChecked(int param) {
int retVal;
if (param > 0 && param < 200) {
retval = foo(param);
} else {
retVal = -1;
}
return retVal;
}