Defer语句
语法
描述
defer 语句用于声明在当前代码块退出时执行的代码,提供一种延迟调用的方式,适合用来做资源释放、关闭文件、状态变更等操作。
当程序执行到作用域结束时(无论是正常结束还是由于 return,break 或
continue 等语句导致),所有在该作用域内声明的 defer 语句会按照先进先出的顺序执行。
defer 语句中不能使用 break 或 continue 语句跳出到 defer 语句之外;在 defer 语句中使用 return,
仅会终止当前 defer 语句的执行,不会影响外层函数的返回。
示例
void example()
{
// 简单的 defer 语句
defer write("hello\n");
// 带代码块的 defer 语句
defer {
int i = 0;
i++;
printf("i = %d\n", i);
}
// 在循环中使用 defer
int n = 4, i = 0, j = 10;
do {
defer write("defer ", j, "\n");
j++;
write("source ", i, "\n");
i++;
} while(i < n);
}
example();
上述代码的执行结果将是:
source 0
defer 11
source 1
defer 12
source 2
defer 13
source 3
defer 14
hello
i = 1
当程序通过 return 语句离开作用域时,在 defer 语句中,可以使用 __return__ 获取当前函数的返回值。
示例
// 资源管理示例
public mixed send_request_directly(object conn, map args) {
queue q = queue.create("", 1);
defer q.close(); // 离开函数后关闭队列
mixed result = q.receive(10);
return result;
}
// 多个 defer 语句按声明顺序的逆序执行
private bool do_logout_in_co(object user, function callback) {
// 结束时清除标记
defer user.delete_temp("logging_out");
bool success = false;
defer {
if (is_function(callback))
callback.call(success);
};
// 锁定用户
string account_id = user.get_account_id();
if (!UserD.lock_user(account_id)) {
return false;
}
// 退出时解锁
defer UserD.unlock_user(account_id);
// 执行登出逻辑
// ...
return true;
}