Reputation: 55
I've been trying to understand callback functions in Rust. After going through a few examples in stackoverflow, I still can't get it to run when the function I want to call is a member function of another struct.
My example is built upon this example post: How to pass a member function of a struct to another struct as callback
struct Person {
name: String
}
impl Person {
pub fn print_name(&self) {
println!("Hello from {}", self.name);
}
}
struct Operation {
cb: fn(&Person),
}
impl Operation {
pub fn caller(&self) {
(self.cb)()
}
}
fn main() {
let person = Person {
name: "Brad".to_string()
};
let op = Operation {
cb: Person::print_name,
};
op.caller()
}
This example doesn't break the linter, but when I try to run it, I get errors about the type and arguments provided.
Compiling playground v0.0.1 (/playground)
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> src/main.rs:17:9
|
17 | (self.cb)()
| ^^^^^^^^^-- supplied 0 arguments
| |
| expected 1 argument
For more information about this error, try `rustc --explain E0061`.
error: could not compile `playground` due to previous error
It seems to me that it cant resolve the self variable so it makes me wonder why the example in the previous post was accepted if that structs function can't actually be called.
Upvotes: 0
Views: 801
Reputation: 2561
In your struct definition, you are saying that the function stored in cb
takes a &Person
argument, so you need to make sure that argument is passed along whenever you try to call the function. You should change the caller
method to handle the argument like so:
struct Person {
name: String
}
impl Person {
pub fn print_name(&self) {
println!("Hello from {}", self.name);
}
}
struct Operation {
cb: Box<dyn Fn()>,
}
impl Operation {
pub fn caller(&self) {
(self.cb)()
}
}
fn main() {
let person = Person {
name: "Brad".to_string()
};
let op = Operation {
cb: Box::new(move || person.print_name()),
};
// person is no longer available here because it has been moved into `op.cp`
//dbg!(person.name); // this will fail
op.caller();
}
Upvotes: 1