728x90
고차원 함수와 클로저
고차원 함수 : 다른 함수를 매개변수로 받는 함수; < > 사이에 매개변수로 받을 함수의 타입을 적어야 한다.
fn again<F: Fn(i32) -> i32 >(f: F, s: i32) -> i32 { f(f(s)) } // 고차원 함수
fn triples(s: i32) -> i32 {
3 * s
}
fn main() {
let mut strength = 26;
println!("My tripled strength equals {}", triples(strength)); // 26
println!("My strength is still {}", strength); // 26
strength = triples(strength);
println!("My strength is now {}", strength); // 78
strength = again(triples, strength);
println!("I got so lucky to turn my strength into {}", strength); // 702
}
익명함수 : pipe(|)사이에 매개변수를 입력하고, 중괄호({})에 입력
fn again<F: Fn(i32) -> i32> (f: F, s: i32) -> i32 {f(f(s))}
fn main() {
strength = 78;
let triples = |n| {3*n}; // 클로져; 익명함수
strength = again(triples,strength);
strength = again(|n|{3*n},strength);
}
클로저 : 익명 함수 내에서 주변 환경(environment)에 있는 변수들을 불러와 사용할 수 있다.
let num = 5;
let plus_num = |x: i32| x + num;
assert_eq!(10, plus_num(5));
mutable variable은 이미 누군가가 소유하고 있기 때문에 사용할 수 없다.
let mut num = 5;
let plus_num = |x: i32| x + num; // 사용불가; num이 이미 소유권을 가지고 있다.
let y = &mut num;
scope를 다르게 해주면 사용이 가능하다.
let mut num = 5;
{
let plus_num = |x: i32| x + num;
} // `plus_num`의 scope가 끝날 때, num의 소유도 끝난다.
let y = &mut num;
moving 클로저 : 둘러싸는(enclosing) 모든 변수의 소유권을 가져와 사용 할 수 있다.
fn again<F: Fn(i32) -> i32> (f: F, s: i32) -> i32 {f(f(s))}
fn main() {
let mut strength = 78;
let triples = |n| {3*n}; // 클로져; 익명함수
strength = again(triples,strength);
//strength = again(|n|{3*n},strength);
println!("{}",strength);
let x: i32 = 42; // x를 정의
let print_add = |s| {
println!("x is {}", x);
x + s // closure x를 사용
};
let res = print_add(strength);
assert_eq!(res, 744);
let m: i32 = 42; // m을 정의
let print_add_move = move |s| { // moving closure 정의
println!("m is {}", m);
m + s
};
let res = print_add_move(strength);
assert_eq!(res, 744)
}
반복자
처음부터 마지막까지 순서대로 반환하는 개체
fn main() {
let mut rng = 0..7;
println!("> {:?}", rng.next());
println!("> {:?}", rng.next());
for n in rng {
print!("{} - ", n);
}
}
컨슈머와 어댑터
컨슈머 : iterator()를 작동시켜 값을 반환한다.
컨슈머는 컴파일을 하지 않기 때문에 타입을 알려줄 필요가 있다.
let rng = 0..1000;
let rngvec = rng.collect::<Vec<i32>>(); // 타입을 알려줘야 한다.
// let rngvec: Vec<i32> = rng.collect(); // 가능
println!("{:?}", rngvec);
.find() : Option함수로 반환한다.
보통 |n|은 n의 참조자로 되어있어서 *n 역참조로 활용하여 사용해야 한다.
let forty_two = rng.find(|n| *n >= 42); //
println("{:?}". forty_two); // Some(42) 출력
어댑터 : 기존 반복자에서 새로운 박복자를 만드는 것
fn is_even(n: i32) -> bool {
n % 2 == 0
}
let rng_even = rng.filter(|n| is_even(*n))
.collect::<Vec<i32>>();
let rng_even_pow3 = rng.filter(|n| is_even(*n))
.map(|n| n * n * n) // 맵을 이용하여 새로운 아이템을 발생시킬 수 있다.
.collect::<Vec<i32>>();
.fold() : 정리 필요
728x90
댓글