我有一段代码在很多地方都可能失败。每增加一个操作(也可能会失败),可读性就会变差。有没有更好的方法来构建这个?有这方面的设计模式吗?
int32_t InitializeMyThingy(void) {
int32_t retcode;
retcode = DoA();
if (retcode != 0) return retcode;
retcode = DoB();
if (retcode != 0) return retcode;
retcode = DoC();
if (retcode != 0) return retcode;
retcode = DoD();
return retcode;
}
Run Code Online (Sandbox Code Playgroud)
或者(更具可读性?):
int32_t InitializeMyThingy(void) {
int32_t retcode;
retcode = DoA();
if (0 == retcode) {
retcode = DoB();
if (0 == retcode) {
retcode = DoC();
if (0 == retcode) {
retcode = DoD();
}
}
}
return retcode;
}
Run Code Online (Sandbox Code Playgroud)
在 C 语言中,SESE(单次进入,单次退出)模式goto通常是合适的:
int32_t InitializeMyThingy(void) {
int32_t retcode;
retcode = DoA();
if (retcode != 0) goto exit;
retcode = DoB();
if (retcode != 0) goto exit;
retcode = DoC();
if (retcode != 0) goto exit;
retcode = DoD();
exit:
return retcode;
}
Run Code Online (Sandbox Code Playgroud)
return就其本身而言,这与您的第一个示例(每次检查后都有语句)没有任何不同。但是,一旦您的代码开始分配资源,该goto方法就会更加清晰:
int32_t InitializeMyThingy(void) {
int32_t retcode = E_FAIL;
A* a = NULL;
B* b = NULL;
C* c = NULL;
a = AllocateA();
if (a == NULL) goto exit;
b = AllocateB(a);
if (b == NULL) goto exit;
c = AllocateC(b);
if (c == NULL) goto exit;
retcode = DoSomething(c);
exit:
free(c);
free(b);
free(a);
return retcode;
}
Run Code Online (Sandbox Code Playgroud)
现在您不必担心弄清楚在每个单独的出口点要清理什么。
不管许多反对者怎么说goto,如果使用得当,它是 C 中最明智的错误处理形式。
关于添加附加操作的可读性,我认为用空格分隔操作有很大帮助。或者,如果您确实想要紧凑性,您可以考虑内联执行操作和错误检查:
if ((retcode = DoA()) != 0) goto exit;
Run Code Online (Sandbox Code Playgroud)