用 scopeguard::defer! 时,必须先声明闭包,再写对应的 try 块,可变借用会在创建闭包时立刻开始,
这里不适合用 defer!(),可以改用 guard 函数,把值放进 scopeguard::ScopeGuard。
因为 ScopeGuard 提供了 Deref 和 DerefMut,访问这个 guard 就和访问它包含的值一样。
struct Resource {}
// ownership of the resource goes into this destructor
// a closure normally serves this purpose
fn release_resource(resource: Resource) {
println!("dropping resource");
}
fn main() {
// obtain the resource, then give it a guard
let resource: Resource = acquire_resource();
let mut resource = guard(resource, release_resource);
// borrowing the resource mutably is another option
// let mut resource = guard(&mut resource, release_resource_by_mut);
// access the enclosed resource through its guard
resource.refresh();
inspect_resource(&resource);
change_resource(&mut resource);
// leaving this scope runs the destructor
// or disable the guard to recover the resource
// without invoking its destructor
// let resource = ScopeGuard::into_inner(resource);
}
从英语翻译·查看原文
With scopeguard::defer!, the closure has to be declared before the equivalent try block, which starts the mutable borrow immediately upon creating that closure,
defer!() isn't suitable here, but the guard function can place your value inside a scopeguard::ScopeGuard insted.
since ScopeGuard supplies Deref and DerefMut, accessing the guard works like accessing the value it holds.
struct Resource {}
// ownership of the resource goes into this destructor
// a closure normally serves this purpose
fn release_resource(resource: Resource) {
println!("dropping resource");
}
fn main() {
// obtain the resource, then give it a guard
let resource: Resource = acquire_resource();
let mut resource = guard(resource, release_resource);
// borrowing the resource mutably is another option
// let mut resource = guard(&mut resource, release_resource_by_mut);
// access the enclosed resource through its guard
resource.refresh();
inspect_resource(&resource);
change_resource(&mut resource);
// leaving this scope runs the destructor
// or disable the guard to recover the resource
// without invoking its destructor
// let resource = ScopeGuard::into_inner(resource);
}