[Rust] Fn, FnMut, FnOnce

0xDave·2022년 6월 22일
0

Rust

목록 보기
4/16
post-thumbnail
fn apply<F>(f: F) where

F: FnOnce() {

    f();  // statement, return value ()
}

fn apply_to_3<F>(f: F) -> i32 where

F: Fn(i32) -> i32 {

    f(3)    //expression
}

fn main() {
    use std::mem;

    let greeting = "hello"; //&str = Stack = Sized, str = Static = Sized

    let mut farewell = "goodbye".to_owned(); //String = Heap = Unsized

    let diary = || {

        println!("I said {}.", greeting);

        farewell.push_str("!!!");
        println!("Then I screamed {}.", farewell);
        println!("Now I can sleep. zzzzz");

        mem::drop(farewell);
    };

    apply(diary);

    let double = |x| 2 * x;

    println!("3 doubled: {}", apply_to_3(double));
}

  1. Fn 은 captured value를 레퍼런스 형태로 가져온다. &T
  2. FnMut 는 captured value를 수정 가능한 레퍼런스로 가져온다. &mut T
  3. FnOnce 는 captured value를 값 그대로 가져온다. T

fn apply<F>(f: F) where

F: FnOnce() {

    f();  // statement, return value ()
}

위 함수를 이해하는데 시간이 조금 걸렸는데, 풀어서 설명하자면

f 를 인자로 받는데 이 때 f 는 함수이며, F 타입이다.
F 타입이라는 말은 FnOnce 타입이라는 뜻이고,
apply 함수는 인자로 받은 f 라는 함수를 실행시켜서 그 값을 리턴한다.




이제 메인 함수의 apply(diary) 를 보면 좀 더 쉽게 이해할 수 있을 것이다.

apply 함수는 FnOnce 타입diary 라는 함수를 인자로 받아서 diary 함수를 실행시켜 그 값을 리턴한다. diary 함수는 Closure 로 마지막에 함수 밖에서 가져온 farewellDrop하기 때문에 FnOnce 타입 이 되는 것이다. FnOnce 타입 은 variable을 가져와서 소비하기 때문에 다시 사용할 수 없다.




//&str = Stack = Sized, str = Static = Sized
//String = Heap = Unsized

이 부분도 중요하니 참고! Heap에 저장되는 String은 공간이 늘어날 수 있기 때문에 .push_str() 을 사용할 수 있었던 것이다.

profile
Just BUIDL :)

0개의 댓글