切换语句,而不是多个嵌套的if-else
Switch statement instead of multiple nested if - else?
我遇到过这样一种情况:我有一堆"系统"需要按顺序初始化,只有在所有正在进行的系统都成功初始化的情况下,下一个系统才能初始化。
这让我想到了一大堆嵌套的if-else语句。下面是一些用于可视化的伪代码。
bool mainInit () {
if (!system1Init ()) {
reportError (); // some error reporting function
}
else {
if (!system2Init ()) {
reportError ();
}
else {
if (!system3Init ()) {
// ... and so on
我发现,当你达到几个级别时,这开始看起来一团糟。
现在,我考虑使用switch语句,从第一个案例开始,成功后再转到其他案例,只有在出现错误时才会中断。
bool mainInit () {
switch (1) {
case 1:
if (!system1Init ()) {
reportError ();
break;
}
case 2:
if (!system2Init ())
reportError ();
break;
}
// ....
}
现在,我更喜欢这个了。我发现它更容易阅读,尤其是有一些不错的评论,但我对编程还很陌生。
所以,我的问题是:看到切换语句传统上不是这样使用的(至少从我所看到的),这样的东西是可以接受的吗,还是会被认为是糟糕的形式?
作为编程的新手,我尽量不养成太多的坏习惯,这些坏习惯可能会让其他程序员感到沮丧和困难。
我做了一个搜索,但我发现的大部分内容都与替换if-else-if语句链有关,而不是替换嵌套语句。
引用数组中的所有系统,例如std::vector<mySystem*>
,然后按顺序循环,在第一次失败时中断。这样,即使对于500多个系统,您的整个代码也会减少到不到5行代码。
建议的开关破解是XY问题解决的一个邪恶例子:你真正的问题是你没有系统数组,而是使用命名变量,从而消除了所有选项,可以更灵活地使用所有系统,就像在循环中一样。
假设所有system#Init()
调用在编译时都是已知的,那么您可以非常容易地将它们放在一个表中,然后在该表上迭代。
typedef (*system_init)(void);
system_init initialization_functions[] =
{
system1Init,
system2Init,
system3Init,
...
systemNInit
};
bool mainInit()
{
for(size_t idx(0); idx < sizeof(initialization_functions) / sizeof(initialization_functions[0]); ++idx)
{
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
}
return true;
}
但是,您现有的代码看起来不正确,因为第一个mainInit()
只调用system1Init()
,然后退出。可能不是你最初想要的。
if(!system1Init())
{
ReportError();
return false;
}
// if you add an else, the system2Init() does not get called
// even if system1Init() succeeds
if(!system2Init())
{
ReportError();
return false;
}
[...]
return true;
这个开关能解决你的问题吗?不是写的那样。也就是说,如果您想用计数器调用mainInit()
函数,它可能会很有用。Drupal使用这种机制:
bool mainInit(int idx)
{
bool r(true);
switch(idx)
{
case 1:
r = system1Init();
break;
case 2:
r = system2Init();
break;
[...]
}
if(!r)
{
ReportError();
}
return r
}
请注意,表机制的工作方式与开关相同。只要所有的代码都在systemNInit()
函数中找到(而且应该是),开关就不会添加任何内容,所以你也可以这样做:
bool mainInit(int idx)
{
if(idx < 0 || idx >= sizeof(initialization_functions) / sizeof(initialization_functions[0]))
{
throw std::range_error("index out of bounds");
}
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
return true;
}
如果你想正确地"去初始化",用索引调用mainInit()
会很有帮助:
int main()
{
for(size_t idx(0); idx < ...; ++idx)
{
if(!mainInit(idx))
{
while(idx > 0)
{
--idx;
mainDeinit(idx);
}
exit(1);
}
}
...app do something here...
}
使用带有明确错误消息的自定义异常,并在main()
中的代码周围添加一个try-catch报告die。例外情况是通过使"糟糕的路径"隐含起来,专门让你的案例看起来很好。
void initX() { ...; throw std::invalid_argument_exception("..."); }
int main() {
try {
init1(); init2(); ... run();
return 0;
} catch (std::exception const& e) {
log(e.what()); exit 42;
}
}
我会这样做:
bool mainInit () {
if (!system1Init ()) {
return(false);
}
if (!system2Init ()) {
return(false);
}
if (!system3Init ()) {
return(false);
}
//...
return(true);
}
//...
if(!mainInit()) {
reportError();
}
- C++嵌套if语句,基本货币交换
- 嵌套 if 中没有返回评估
- 具有嵌套 if-else 的循环的时间复杂度
- 嵌套的 else 语句 c++
- 如何退出 for 循环内的嵌套 if-else 语句?(C/C++)
- 使用嵌套 if 语句的意外结果
- 在While循环中嵌套if语句
- C++ 嵌套'if'语句中的所有代码都会运行,即使这会更改外部语句的布尔值?
- 嵌套 if 与串行逻辑博克斯
- 简单嵌套"If else"语句
- 如何处理鼠标点击逻辑的许多嵌套if语句
- 嵌套if中的作用域不明确
- 嵌套if语句,同时也删除选项
- 嵌套IF语句vs IF- else
- C++:不应用于简单嵌套if-then-else语句的条件
- 嵌套 if 语句中的左值错误
- 嵌套if VS . 2独立if——性能方面
- 嵌套if -用c++进行嵌套if检查
- 嵌套'if'语句的一个'else'
- 使用GCC优化C/ c++循环中的嵌套if语句