ํด๋กœ์ €(Closure)

ํด๋กœ์ € ํ˜น์€ ๋žŒ๋‹คํ‘œํ˜„์‹์€ ์ต๋ช…ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ Fn,FnMut, FnOnce ๋ผ๋Š” ํŠน๋ณ„ํ•œ ํŠธ๋ ˆ์ž‡์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค:

fn apply_with_log(func: impl FnOnce(i32) -> i32, input: i32) -> i32 {
    println!("Calling function on {input}");
    func(input)
}

fn main() {
    let add_3 = |x| x + 3;
    println!("add_3: {}", apply_with_log(add_3, 10));
    println!("add_3: {}", apply_with_log(add_3, 20));

    let mut v = Vec::new();
    let mut accumulate = |x: i32| {
        v.push(x);
        v.iter().sum::<i32>()
    };
    println!("accumulate: {}", apply_with_log(&mut accumulate, 4));
    println!("accumulate: {}", apply_with_log(&mut accumulate, 5));

    let multiply_sum = |x| x * v.into_iter().sum::<i32>();
    println!("multiply_sum: {}", apply_with_log(multiply_sum, 3));
}

Fn(์˜ˆ๋ฅผ ๋“ค์–ด add_3)์€ ์บก์ฒ˜๋œ ๊ฐ’์„ ์†Œ๋ชจ๋„ ๋ณ€๊ฒฝ๋„ ํ•˜์ง€ ์•Š๊ณ , ํ˜น์€ ์–ด๋–ค ๊ฒƒ๋„ ์บก์ณํ•˜์ง€ ์•Š์•˜์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋™์‹œ์— ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

FnMut(์˜ˆ๋ฅผ ๋“ค์–ด accumulate)๋Š” ์บก์ฒ˜๋œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋™์‹œ์— ํ˜ธ์ถœ ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

FnOnce (์˜ˆ๋ฅผ ๋“ค์–ด multiply_sum)๋Š” ํ•œ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๋ฉฐ ์บก์ฒ˜๋œ ๊ฐ’์„ ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค.

FnMut ๋Š” FnOnce์˜ ํ•˜์œ„ํƒ€์ž…์ž…๋‹ˆ๋‹ค. Fn์€ FnMut๊ณผ FnOnce์˜ ํ•˜์œ„ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์ฆ‰, FnMut๋Š” FnOnce๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ณณ์ด๋ฉด ์–ด๋””์„œ๋‚˜ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ณ  Fn์€ FnMut์™€ FnOnce๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ณณ์ด๋ฉด ์–ด๋””๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํด๋กœ์ €๊ฐ€ ๋ฌด์—‡์„ ์บก์ณํ•˜๋Š”์ง€์— ๋”ฐ๋ผ Copy(์˜ˆ๋ฅผ ๋“ค์–ด add_3)๊ณผ Clone(์˜ˆ๋ฅผ ๋“ค์–ด multiply_sum)์„ ์•Œ์•„์„œ ์ถ”๋ก ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋กœ์ ธ๋Š”, ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์บก์ณ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. move ํ‚ค์›Œ๋“œ๋ฅผ ์“ฐ๋ฉด ๊ฐ’์œผ๋กœ ์บก์ณ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

fn make_greeter(prefix: String) -> impl Fn(&str) {
    return move |name| println!("{} {}", prefix, name)
}

fn main() {
    let hi = make_greeter("Hi".to_string());
    hi("there");
}