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

results matching ""

    No results matching ""