我想做类似于C std::bind
的事情,并将绑定功能指针作为参数传递给另一个函数。
下面的代码证明了我失败的尝试,并希望说明我要做的事情。
pub struct MyStruct {
x: i64
}
impl MyStruct {
pub fn struct_function(&mut self, val: i64) {
self.x += val;
}
}
fn normal_function(val: i64) {
println!( "sum -> {}", val + 1);
}
fn do_something_with_a_function(f: fn(i64)) {
f(23);
}
fn main() {
// This works as you'd expect
do_something_with_a_function(normal_function as fn(i64));
// What I'd like to do
// This attempts to use a closure, but throws an error.
let instance = MyStruct{x: 0};
let instance_function = |val: i64|{instance.struct_function(val)};
do_something_with_a_function(instance_function as fn(i64));
}
错误:
错误:非量表铸件:
[closure@src/main.rs:25:29: 25:72 instance:&mut MyStruct]
为fn(i64)
这是关于函数指针fn(i64)
之间的差异,该指针只是指向某些代码的指针,而闭合是一个不愿意的结构,带有某些数据(上下文)和一个调用方法。
要通过关闭,您需要对可呼叫类型进行通用函数:
fn do_something_with_a_function<F: FnMut(i64)>(mut f: F) {
f(23);
}
这说它可以采用任何实现FnMut(i64)
的类型。FnMut
意味着在调用其上下文时,它会得到可变的引用,在这种情况下,需要在其上调用可变方法(在其他情况下,可以使用Fn
或FnOnce
;请参阅"封闭式"一章)。普通功能还实现了这些特征。f
必须为mut
,其原因与需要FnMut
相同的原因。
这是更新的呼叫者:
fn main() {
do_something_with_a_function(normal_function);
let mut instance = MyStruct{x: 0};
let mut instance_function = |val: i64|{instance.struct_function(val)};
do_something_with_a_function(&mut instance_function);
do_something_with_a_function(&mut instance_function);
}
请注意,instance_function
现在是可突变的,&mut
引用到do_something_with_a_function()
中。如果它是按值传递的(曾经有效的)已移动,因此您不能再次使用它。
(游乐场)