#programminglanguage #rust > [!introduction] > 러스트에서는 마치 어떤 값을 다루는 것처럼 함수를 변수에 저장하거나, 다른 함수에 인자로 전달할 수도 있습니다. 이번 글에서는 값처럼 다루어지는 익명 함수, 클로저*closure*에 대해 알아봅니다. ## 논리를 저장하다 ```rust //unwrap_or_else를 사용하면 Result가 Ok일 때 Ok 안의 값을 반환하고, Err일 때 클로저 안의 코드를 호출한다. let config = Config::build(&args).unwrap_or_else(|err| { //표준 에러 출력을 위한 eprintln! 매크로 eprintln!("Problem parsing arguments: {err}"); process::exit(1); }); ``` 위에 주어진 예시 코드에서 `unwrap_or_else` 메서드 안에 클로저 표현식이 사용되었는데, 이 메서드를 호출한 인스턴스가 의도된 타입이 아닐 때 인자로 주어진 클로저를 실행하게 된다. 사실 클로저 표현식은 함수와 유사한데, `fn`과 소괄호`()`를 쓰지 않는 대신. `||` 사이에 매개변수가 들어가고 중괄호를 통해 함수 본문을 정의하면 된다. 그럼에도 불구하고 클로저가 함수와 동떨어져 보이는 것은 일반적으로 클로저를 작성할 때 매개변수와 반환 값의 타입을 명시하지 않고 때에 따라서는 중괄호`{}`도 생략하기 때문인데, 생략된 코드를 추가하면 다음과 같다. ```rust let config = Config::build(&args).unwrap_or_else(|err: &str| { //표준 에러 출력을 위한 eprintln! 매크로 eprintln!("Problem parsing arguments: {err}"); process::exit(1); }); ``` 이렇듯 클로저에서 사용되는 매개변수와 반환 값의 타입은 컴파일러가 알아서 추론하기 때문에, 같은 클로저를 여러 번 사용할 때 처음과 다른 타입의 인자를 넣으면 에러가 발생한다. ```rust // closure-example/main.rs let example_closure = |x| x; let s = example_closure(String::from("hello")); let n = example_closure(5); ``` ```bash $ cargo run Compiling closure-example v0.1.0 (file:///projects/closure-example) error[E0308]: mismatched types --> src/main.rs:5:29 | 5 | let n = example_closure(5); | --------------- ^- help: try using a conversion method: `.to_string()` | | | | | expected struct `String`, found integer | arguments to this function are incorrect | note: closure parameter defined here --> src/main.rs:2:28 | 2 | let example_closure = |x| x; | ^ For more information about this error, try `rustc --explain E0308`. error: could not compile `closure-example` due to previous error ``` --- ## 참고 자료 & 더보기 + [The Rust Programming Language(한국어판), 13. 함수형 언어의 특성: 반복자와 클로저](https://doc.rust-kr.org/ch13-00-functional-features.html) + [The Rust Programming Language(한국어판), 19.4. 고급 함수와 클로저](https://doc.rust-kr.org/ch19-05-advanced-functions-and-closures.html)