我是 Rust 新手,我想知道解决这个基本示例的最佳方法是什么。我通过返回一个闭包来组合两个
MathLogFn
类型的函数。据我了解,需要关闭才能访问周围环境中的math_log_fns
。
下面的代码可以编译,但是有没有办法重构它,使
combine_math_log_fns()
的返回类型为 MathLogFn
?
type MathLogFn = fn(u32, u32);
fn log_sum(n1: u32, n2: u32) {
println!("{}", n1 + n2);
}
fn log_product(n1: u32, n2: u32) {
println!("{}", n1 * n2);
}
fn combine_math_log_fns(math_log_fns: Vec<MathLogFn>) -> Box<dyn Fn(u32, u32)> {
Box::new(move |n1: u32, n2: u32| {
for mlf in &math_log_fns {
mlf(n1, n2);
}
})
}
fn main() {
let mlfs: Vec<Box<dyn Fn(u32, u32)>> = vec![
Box::new(log_sum),
Box::new(log_product),
combine_math_log_fns(vec![log_sum, log_product]),
];
}
您尝试了什么以及您期待什么?
我尝试重构,但编译器给出错误,指出它无法访问
math_log_fns
,除非使用闭包:
fn combine_math_log_fns(math_log_fns: Vec<MathLogFn>) -> MathLogFn {
fn combined(n1: u32, n2: u32) {
for mlf in &math_log_fns {
mlf(n1, n2);
}
}
combined
}
这个答案扩展了我写的评论。
在
type MathLogFn = fn(u32, u32);
行中,fn(u32, u32)
是一个函数指针类型。这些指针只能指向代码,而不能指向额外的运行时数据。 closure 是不同的;它可以捕获额外的运行时数据,特别是来自其环境的变量。
fn log_sum
不从其环境中捕获任何变量,因此它可以用作函数指针fn log_product
不从其环境中捕获任何变量,因此它可以用作函数指针fn combined
使用环境中的 math_log_fns
,因此必须将其转换为闭包我们不知道
combine_math_log_fns
必须返回一个闭包,您可以选择:
Box<dyn Fn(u32, u32)>
无法克隆,如果添加 Clone
绑定,克隆效率会很低Rc<dyn Fn(u32, u32)>
,可高效克隆Arc<dyn Fn(u32, u32) + Send + Sync>
,类似于 Rc
,但可在多线程上下文中使用然后,您不妨使用您选择的类型重新定义类型别名,以获得最大的互操作性:
type MathLogFn = Box<dyn Fn(u32, u32)>;