当某些控制路径会丢弃某个值时,该点之后的所有控制路径都无法再次访问该变量。在下面的示例中,在 if 语句之后访问保护将是一个错误。尽管如此,Rust 实际上并没有丢弃该值,直到它超出范围。为什么不呢?我想不出任何让对象保持活动的合理理由,而且它似乎很可能导致死锁(这就是我遇到这种行为的原因)。
use scopeguard; // 1.2.0
fn func(guard: impl std::fmt::Debug) {
if false {
drop(guard);
}
println!("guard is not yet dropped")
}
fn main() {
let guard = scopeguard::guard((), |_| println!("value dropped"));
func(guard);
}
相关问题“为什么这个值在最后一次使用后不会被删除?”有所不同,因为该值在最后一次使用后仍然可以命名。在这个问题中,该值在 if 语句之后是不可命名的(接受的答案中显示了例外情况)。
Rust 遵循一致的语义规范,其中删除取决于超出范围。虽然替代语义是可能的,并且可能是未来 Rust版本的主题,但如何尽早删除事物的确切规则可能会增加复杂性并引起混淆。例如,
return
语句将是一个例外,因为此代码有效:如果您的代码特别容易出现死锁,重构可能会有所帮助。否则,只需移至
drop
afterif
或 alsodrop
in即可else
。