8.2.1 Capturing
클로저는 본질적으로 유연하고 주해 없이 동작할 수 있는 기능성을 갖는다. 이는 캡쳐가 상황에 맞춰 유연하게 때로는 이동하고 때로는 차용 할 수 있게끔 한다. 클로저들은 변수를 캡쳐 할 수 있다.
- 참조를 통해:
&T - 가변참조를 통해:
&mut T - 값을 통해:
T - by reference:
&T - by mutable reference:
&mut T - by value:
T
그들은 우선적으로 참조를 통해 변수를 캡쳐하고 필요에 따라 하위 방법을 취한다.
fn main() {
use std::mem;
let color = "green";
// `color`를 출력하는 클로저는 `color`를 즉각적 대여(`&`)하고
// `print` 변수에 대여와 클로저를 저장한다. `print`가 범위에서 벗어날 때까지
// 대여는 유지된다. `println!`은 `참조에 의해`서만 요구되므로
// 더 제한적인 것을 강요하지 않는다.
let print = || println!("`color`: {}", color);
// Call the closure using the borrow.
print();
print();
let mut count = 0;
// `count`를 증가시키는 클로저는 `&mut count` 또는 `count` 중 하나를
// 취할 수 있지만 `&mut count`이 덜 제한적이므로 이를 취한다.
// 즉각적 대여한 `count`. `mut`가 `inc`에 필요한 이유는 `&mut`이 내부에
// 저장되기 때문이다. 따라서 클로저의 호출은 `mut`을 요구하는 클로저를
// 변경한다.
let mut inc = || {
count += 1;
println!("`count`: {}", count);
};
// 클로저 호출 .
inc();
inc();
//let reborrow = &mut count;
// ^ TODO: 해당 라인의 주석을 제거해보세요.
// 복사가 아닌 타입.
let movable = Box::new(3);
// `mem::drop`은 `T`를 요구하므로 이는 값을 취해야 한다. 복사 타입은
// 클로저로 복사되어 원본은 변경되지 않는다. 복사가 아니면 이동되야 하고
// 그래서 `movable`이 즉시 클로저로 이동된다.
let consume = || {
println!("`movable`: {:?}", movable);
mem::drop(movable);
};
// `comsume`은 변수를 소비하므로 한번만 호출 될 수 있다.
consume();
//consume();
// ^ TODO: 해당 라인의 주석을 제거해보세요.
}See also:
Box and std::mem::drop