如何避免循环中丑陋的break和continue
程序员文章站
2024-01-07 08:29:22
...
如何避免循环中丑陋的break和continue
这两天逛知乎,看到一篇帖子《为何部分程序员从不使用 break 或 continue 语句?》
目前工作七八年的经历来看,存在即合理,循环中绝对不使用break和continue是有点极端了,过于教条主义,但是滥用或者不注意使用break和continue会严重影响代码的可读性和扩展性,影响后期其他开发人员维护。例如以下代码
for (int i = 0; i < N; i++) {
Data d = list.get(i);
if (/* if condition of d */) {
continue;
} else if (/* if condition of d */) {
continue;
} else if (/* if condition of d */) {
continue;
}
// handle something
if (/*some condition*/) {
break;
}
// handle another something
}
在一个循环中根据不同的条件有时候需要跳出循环,有时候需要continue。这种代码运行绝对没问题,运行结果是正确的,但是如果多加几个需求,再多加几个break,即使有注释过半年后再看代码也要花费一些精力才能确定代码逻辑。如果非本人维护这份代码,那简直是噩梦。
问题来了,如何消除上述代码中丑陋的break和continue呢?
剥茧抽丝
循环的存在无非就是为了每次处理序列元素中的一个元素,或者一个递增递减条件。因此我们可以将循环体处理的元素作为函数参数传递到函数中,然后在函数中处理,将continue转换为函数中的return。
class Data {
};
int continue_function(Data data) {
if (/* if condition of data */) {
return 0;
} else if (/* if condition of data */) {
return 0;
} else if (/* if condition of data */) {
return 0;
}
// handle something
if (/*some condition*/) {
return -1;
}
// handle another something
return 0;
}
for (int i = 0; i < N; i++) {
Data d = list.get(i);
if (0 != continue_function(d)) {
break;
}
}
上述函数中就将循环体中的遍历元素作为参数在continue_function中处理,然后通过return及其返回值替代break和continue,最终循环体中只有一个break,没有continue。
局限性
当然这种方法也有局限性,其一、函数调用时候参数会有出栈入栈操作,系统调用函数也要消耗性能;其二、循环体中需要用到的局部变量多的时候会造成continue_function的参数过多,进而降低可读性。
对于第一种情况如果在c++中我们可以使用inline关键词声明函数为内联函数,并且参数传递使用&引用传递,减少参数拷贝;
对于第二种情况只能是重新组织代码逻辑,优化数据结构定义,需要根据实际情况操作;