scopeguard::defer!를 쓰면 try에 해당하는 블록 앞에 클로저를 선언해야 해서 클로저를 만드는 즉시 가변 빌림이 시작돼요,
여기에는 defer!()가 맞지 않고, 대신 guard 함수로 값을 scopeguard::ScopeGuard 안에 넣으면 돼요.
ScopeGuard가 Deref와 DerefMut를 제공하므로 가드 안의 값에 접근하듯 가드를 사용하면 돼요.
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);
}