fn main() {
// Increment via closures and functions.
fn function(i: i32) -> i32 { i + 1 }
// Closures are anonymous, here we are binding them to references
// Annotation is identical to function annotation but is optional
// as are the `{}` wrapping the body. These nameless functions
// are assigned to appropriately named variables.
let closure_annotated = |i: i32| -> i32 { i + 1 };
let closure_inferred = |i | i + 1 ;
let i = 1;
// Call the function and closures.
println!("function: {}", function(i));
println!("closure_annotated: {}", closure_annotated(i));
println!("closure_inferred: {}", closure_inferred(i));
// A closure taking no arguments which returns an `i32`.
// The return type is inferred.
let one = || 1;
println!("closure returning one: {}", one());
}
Closure
는 1회용 function이라고 생각하면 된다. 기본 형태는 ||
을 인자로 받아서 리턴하는 형태이며, 타입지정이 의무는 아니다.
function과 같은 기능을 하지만 function에서 할 수 없는 Capturing 이 가능하다. Capturing 은 함수 밖에서 선언한 변수를 사용할 수 있는 것을 말한다. 아래 예제를 보면
fn main() {
use std::mem;
let color = String::from("green");
let print = || println!("`color`: {}", color);
함수 밖에서 선언된 color
를 Closure
안에서 사용한 것을 볼 수 있다. 원래 fn 으로 구성된 function은 이렇게 할 수 없다.
let s: &str = "a";
let ss: String = s.to_owned();
let v: &[i32] = &[1, 2];
let vv: Vec<i32> = v.to_owned();
to_owned
는 빌려온 데이터를 다시 소유할 수 있게 해주는 메소드다.
빌려온 &str
을 String
으로 바꿔주고, 빌려온 &[i32]
를 Vec<i32>
로 바꿔준다.