永不嵌套 — Nev R. Nester
发布: (2026年5月1日 GMT+8 00:42)
4 分钟阅读
原文: Dev.to
Source: Dev.to
永不嵌套
永不嵌套本质上是一条建议:避免超过三个缩进层级的嵌套。
… 如果你需要超过 3 级的缩进,那你已经完蛋了,应该去修正你的程序。
— Linus Torvalds
void process_order(User *u, Order *o, Payment *p) {
if (u != NULL) {
if (o != NULL) {
if (p != NULL) {
if (!u->is_banned) {
if (o->total > 0) {
if (check_inventory(o)) {
if (p->balance >= o->total) {
if (execute_payment(u, o, p)) {
if (finalize_order(o)) {
if (send_receipt(u)) {
printf("Success\n");
} else {
log_error("Receipt failed");
}
} else {
log_error("Finalize failed");
}
} else {
log_error("Payment failed");
}
} else {
log_error("Insufficient funds");
}
} else {
log_error("Out of stock");
}
} else {
log_error("Order empty");
}
} else {
log_error("User banned");
}
} else {
log_error("No payment info");
}
} else {
log_error("No order info");
}
} else {
log_error("No user info");
}
}这个例子显得荒唐。深度嵌套的 if 语句或循环难以阅读,使代码看起来像是故意写得晦涩。
下面的更实际的代码片段同样说明了这个问题:
// calculator function
int calculate_final(int a, int b, char op) {
if (a != 0) {
if (b != 0) {
if (op == '+') {
return a + b;
} else {
if (op == '-') {
return a - b;
} else {
return 0;
}
}
} else {
return -1;
}
} else {
return -1;
}
}提取
提取是永不嵌套中的一种技术,它把代码片段移动到单独的函数中,从而降低嵌套深度。
int is_invalid(int a, int b) {
return (a == 0 || b == 0);
}
int calculate_final(int a, int b, char op) {
if (is_invalid(a, b)) {
return -1;
}
if (op == '+') {
return a + b;
if (op == '-' {
return a - b;
}
}
return 0;
}这里把第一个条件提取到 is_invalid 中,使主函数更简洁。
守卫子句
守卫子句在函数开头处理“错误”或边缘情况,让后面的代码可以假设数据是有效的。使用 is_invalid 辅助函数作为守卫可以显著减少缩进。
int is_invalid(int a, int b) {
return (a == 0 || b == 0);
}
int calculate_final(int a, int b, char op) {
if (is_invalid(a, b)) {
return -1;
}
if (op == '+') {
return a + b;
}
if (op == '-') {
return a - b;
}
return 0;
}我应该总是避免嵌套吗?
不可能永远不超过三层嵌套,但保持嵌套浅显有助于提升可读性。当代码看起来层层嵌套时,就是该重构的信号——提取方法、引入守卫子句,或重新思考算法。平坦、易读的代码更易维护,也不太会在以后“咬你”。