물론 넌 할 수있어:
fn fun_test(value: i32, f: &dyn Fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn times2(value: i32) -> i32 {
2 * value
}
fn main() {
fun_test(5, ×2);
}
이것은 Rust이기 때문에 클로저 의 소유권과 수명 을 고려해야합니다 .
TL; DR; 기본적으로 3 가지 유형의 클로저 (호출 가능한 객체)가 있습니다.
Fn
: 캡처 한 개체를 수정할 수 없습니다.
FnMut
: 캡처 한 객체를 수정할 수 있습니다.
FnOnce
: 가장 제한적입니다. 호출 될 때 자체 및 캡처를 소비하므로 한 번만 호출 할 수 있습니다.
클로저는 Fn, FnMut 및 FnOnce를 언제 구현합니까?를 참조하십시오 . 상세 사항은
클로저와 같은 간단한 함수 포인터를 사용하는 경우 캡처 세트가 비어 있고 Fn
맛 이 있습니다.
더 멋진 일을하고 싶다면 람다 함수를 사용해야합니다.
Rust에는 C 에서처럼 작동하는 함수에 대한 적절한 포인터가 있습니다. 그 유형은 예를 들어 fn(i32) -> i32
. Fn(i32) -> i32
, FnMut(i32) -> i32
그리고 FnOnce(i32) -> i32
실제로 특징이다. 함수에 대한 포인터는 항상이 세 가지를 모두 구현하지만, Rust에는 함수에 대한 포인터 (캡처 세트가 비어 있는지에 따라)로 변환되거나 변환되지 않을 수도있는 클로저도 있지만 이러한 특성 중 일부를 구현합니다.
예를 들어 위의 예를 확장 할 수 있습니다.
fn fun_test_impl(value: i32, f: impl Fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn fun_test_dyn(value: i32, f: &dyn Fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn fun_test_ptr(value: i32, f: fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn times2(value: i32) -> i32 {
2 * value
}
fn main() {
let y = 2;
fun_test_impl(5, times2);
fun_test_impl(5, |x| 2*x);
fun_test_impl(5, |x| y*x);
fun_test_dyn(5, ×2);
fun_test_dyn(5, &|x| 2*x);
fun_test_dyn(5, &|x| y*x);
fun_test_ptr(5, times2);
fun_test_ptr(5, |x| 2*x);
fun_test_ptr(5, |x| y*x);
}