永不嵌套 — 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;
}

我应该总是避免嵌套吗?

不可能永远不超过三层嵌套,但保持嵌套浅显有助于提升可读性。当代码看起来层层嵌套时,就是该重构的信号——提取方法、引入守卫子句,或重新思考算法。平坦、易读的代码更易维护,也不太会在以后“咬你”。

0 浏览
Back to Blog

相关文章

阅读更多 »

asyncio 陷阱:3 小时 Bug

上周,我的老板让我加速一个旧的 web‑scraping 项目。我想,“没问题——我直接把 asyncio 抛进去,进行并发抓取,理论上……”

模型越智能,节省越多。

神话:更智能的模型会让插件变得多余。自从 WOZCODE 推出以来,许多 Claude Code 高级用户低声说插件的优势将会消失。