如何将方法作为回调/处理程序参数传递给函数?

时间:2020-02-24 22:31:46

标签: rust

以下executor函数接受一个函数并使用参数对其进行调用:

fn executor(func: &dyn Fn(String)) {
    // Invoke the callback
    func(String::from("Hello"));
}

此代码无法编译:

struct MyStruct {
    the_answer: u32,
}

impl MyStruct {
    pub fn run(&self) {
        executor(&self.printer_method); // <--- Does not compile - rustc(E0615)

        executor(&MyStruct::printer_associated_func); // <--- ...but this does.
    }

    fn printer_method(&self, msg: String) {
        // Access to self.the_answer
        println!(
            "The answer is {}, your message is: {}",
            self.the_answer, msg
        );
    }

    fn printer_associated_func(msg: String) {
        // No access to self.the_answer
        println!("printer: {}", msg);
    }
}

fn main() {
    let my_struct = MyStruct { the_answer: 42 };
    my_struct.run();
}

完整的错误消息:

error[E0615]: attempted to take value of method `printer_method` on type `&MyStruct`
  --> src/main.rs:12:24
   |
12 |         executor(&self.printer_method);
   |                        ^^^^^^^^^^^^^^ help: use parentheses to call the method: `printer_method(...)`

如何将方法(即不是关联的函数或仅仅是无上下文的函数)传递给executor()函数?

如果我在这里达到语言的极限,我必须从回调内部访问成员变量self.the_answer的哪些选择?

1 个答案:

答案 0 :(得分:6)

您无法使用编写的语法获得指向成员函数的可调用指针,因为要调用它,您需要一个self,因此可调用对象需要捕获self,但是函数指针始终有一个空的捕获集。也就是说,如果获得指向MyStruct::printer_method的指针,则函数实际上接受两个参数,而不是一个。

要执行所需的操作,可以使用一个闭包来捕获self

executor(&|msg| self.printer_method(msg));

请注意,实际上您需要一个指向闭包的指针,因为您传递的是dyn Fn而不是impl Fn