在我的代码中,我有一个if语句,如下所示:
if(someFunction1(a) || someFunction2(b->b1,c) || *d == null || somefunction3(e) > f * g || !e->e1 || ...){
return 0;
} else {
do_something;
}
在我的代码中,实变量和函数名称的条件几乎有三行,看起来很容易被忽略。所以我决定把它重写成形式:
if(someFunction1(a)){
return 0;
} else if(someFunction2(b->b1,c)){
return 0;
} else if(*d == null){
return 0;
} else if(somefunction3(e) > f * g){
return 0;
} else if(!e->e1){
return 0;
} else if(...){
return 0;
} else{
do_something;
}
有什么理由我不应该这样做吗?
答案 0 :(得分:17)
从纯粹的语义 - 句法角度来看,它们之间没有任何有效的区别。但是,如果您关心可读性,为什么不使用" datenwolf" 格式化风格 - 我在过去的5个项目中开发了这种风格:
if( someFunction1(a)
|| someFunction2(b->b1,c)
|| *d == null
|| somefunction3(e) > f * g
|| !e->e1
|| ...
){
return 0;
} else {
do_something;
}
你看到一切都很美妙吗?它看起来像一个管子,程序正在倒塌,直到达到满足条件。如果你有&&
,它看起来像是一系列不能被打破的操作。
答案 1 :(得分:6)
由于您的可读性,您可能想要将长条件重新排列为谓词变量,这些变量说明为什么必须返回零。
<input type="file" nv-file-select="" uploader="uploader" multiple />
这是Martin Fowler的Decompose Conditional重构。
答案 2 :(得分:5)
选项1:
选项2:
答案 3 :(得分:3)
除了所涉及的冗余之外,我认为此代码中没有任何其他问题。如果你必须对return语句进行更改,则必须根据你的实现在6个位置进行更改。
但是在第一次实现中不会出现冗余。
两者都不相似。
答案 4 :(得分:2)
首先,如果不提供一些理由,你就无法回答这个问题,否则答案将变得完全主观。我会警惕那些回答“喜欢这样,因为我最喜欢这样”的人,没有提供任何理由。
查看代码,显然在函数内部进行了大量错误检查。在一个真实的代码示例中,所有这些错误处理通常需要大量注释来描述每个错误条件,因为具有大量错误处理的函数往往很复杂。
鉴于此,将代码编写为一个语句并不是一个好主意,因为如果你必须在语句中间插入注释,代码就会变得一团糟。
根据上述理由,写这样的最佳方式可能是:
/* comments here */
if(someFunction1(a)){
return 0;
}
/* comments here */
if(someFunction2(b->b1,c)){
return 0;
}
...
/* if we got here, then there are no errors */
do_something();
如果需要在错误检查之间执行代码,这也具有可维护的优点。或者,如果您希望将一些更复杂的表达式拆分为多行以便于阅读。
即使有很多情况下多个return语句都有可能产生混乱的代码,但这不是其中之一。在这种情况下,多个返回语句实际上提高了可读性/可维护性。你不应该教条地避免多个return语句,因为某些编码标准会告诉你这样做。
答案 5 :(得分:0)
您可以通过以下方式执行此操作
int not_valid = someFunction1(a) ||
someFunction2(b->b1,c) ||
*d == null ||
somefunction3(e) > f * g ||
!e->e1 || ...;
if ( !not_valid )
{
do_something;
}
return !not_valid;
您可以选择更合适的名称,而不是not_valid。:)