struct实例函数指针作为函数参数(类似于std :: bind bint in C )



我想做类似于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意味着在调用其上下文时,它会得到可变的引用,在这种情况下,需要在其上调用可变方法(在其他情况下,可以使用FnFnOnce;请参阅"封闭式"一章)。普通功能还实现了这些特征。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()中。如果它是按值传递的(曾经有效的)已移动,因此您不能再次使用它。

(游乐场)

最新更新