rust 如果闭包捕获变量,如何将其作为函数参数传递

voj3qocg  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(122)

我试图在Rust中使用高阶函数,我很纠结,因为我想传递的参数函数是一个捕捉值的闭包。
这是我的第一次尝试(playground link):

/// Takes a value, n, doubles it, and then applies the function f
fn double_then_f(n:u64, f: fn(u64) -> u64) -> u64 {
    f(n * 2)
}

fn main() {
    // Simple f closure works just fine
    let example_1 = double_then_f(5, |n| n + 1);
    
    // More realistic closure doesn't work
    let dynamic_value = vec![1, 2, 3].iter().sum::<u64>();
    let example_2 = double_then_f(5, |n| n + dynamic_value);
}

无法使用编译

note: expected fn pointer `fn(u64) -> u64`
                 found closure `[closure@src/main.rs:12:38: 12:41]`
note: closures can only be coerced to `fn` types if they do not capture any variables

在阅读了Fn trait和fn类型之间的区别之后,这是我的第二次尝试:

/// Takes a value, n, doubles it, and then applies the function f
fn double_then_f(n:u64, f: Box<dyn Fn(u64) -> u64>) -> u64 {
    f(n * 2)
}

fn main() {
    // Simple f closure works just fine
    let example_1 = double_then_f(5, Box::new(|n| n + 1));
    
    // More realistic closure doesn't work
    let dynamic_value = vec![1, 2, 3].iter().sum::<u64>();
    let example_2 = double_then_f(5, Box::new(|n| n + dynamic_value));
}

这也无法编译,并出现与生存期相关的错误,即“cast要求dynamic_value'static借用“。我猜它所谈论的cast是将我的闭包封装到trait对象中?
我能做些什么来使这个代码工作?

tzdcorbm

tzdcorbm1#

使用Fn特性!

fn double_then_f<F: Fn(u64) -> u64>(n:u64, f: F) -> u64 {
    f(n * 2)
}

fn main() {
    let example_1 = double_then_f(5, |n| n + 1);
    
    let dynamic_value = vec![1, 2, 3].iter().sum::<u64>();
    let example_2 = double_then_f(5, |n| n + dynamic_value);
}

相关问题