我如何在 Rust 中将结构方法作为回调传递?
How can i pass a struct method as callback in Rust?
在 C++ 中,我使用这个。
class A{
public:
void read();
}
class B{
public:
void setCallback(std::function<void()> f){
...
}
}
int main(){
A a;
B b;
b.setCallback(std::bind(&A::read,&a));
}
我可以在 Rust 中实现相同的功能吗?
这对你有用吗?
struct A {
x: u32,
}
impl A {
fn do_something(&mut self) {
self.x += 1;
}
}
struct B<F> {
callback: Option<F>,
}
impl<F: FnMut()> B<F> {
fn set_callback(&mut self, callback: F) {
self.callback = Some(callback);
}
fn call_callback(&mut self) {
self.callback.as_mut().map(|cb| cb());
}
}
fn main() {
let mut a = A { x: 0, };
let mut b = B { callback: None, };
b.set_callback(|| a.do_something());
b.call_callback();
assert_eq!(a.x, 1);
}
我保守地猜测了可变性要求是什么。
@isaactfa 的回答是正确的,但是 std::function
使用动态调度并且更像 Box<dyn Fn()>
而不是使用泛型。
struct B<'a> {
callback: Option<Box<dyn FnMut() + 'a>>,
}
impl<'a> B<'a> {
fn set_callback(&mut self, callback: Box<dyn FnMut() + 'a>) {
self.callback = Some(callback);
}
fn call_callback(&mut self) {
self.callback.as_mut().map(|cb| cb());
}
}
fn main() {
let mut a = A { x: 0 };
let mut b = B { callback: None };
b.set_callback(Box::new(|| a.do_something()));
b.call_callback();
drop(b); // It is necessary for the code to not use `a` while it's borrowed by the closure
assert_eq!(a.x, 1);
}
您可以通过在结构方法中创建 Box
来获得更多便利,因此调用者不必创建它:
impl<'a> B<'a> {
fn set_callback(&mut self, callback: impl FnMut() + 'a) {
self.callback = Some(Box::new(callback));
}
}
在 C++ 中,我使用这个。
class A{
public:
void read();
}
class B{
public:
void setCallback(std::function<void()> f){
...
}
}
int main(){
A a;
B b;
b.setCallback(std::bind(&A::read,&a));
}
我可以在 Rust 中实现相同的功能吗?
这对你有用吗?
struct A {
x: u32,
}
impl A {
fn do_something(&mut self) {
self.x += 1;
}
}
struct B<F> {
callback: Option<F>,
}
impl<F: FnMut()> B<F> {
fn set_callback(&mut self, callback: F) {
self.callback = Some(callback);
}
fn call_callback(&mut self) {
self.callback.as_mut().map(|cb| cb());
}
}
fn main() {
let mut a = A { x: 0, };
let mut b = B { callback: None, };
b.set_callback(|| a.do_something());
b.call_callback();
assert_eq!(a.x, 1);
}
我保守地猜测了可变性要求是什么。
@isaactfa 的回答是正确的,但是 std::function
使用动态调度并且更像 Box<dyn Fn()>
而不是使用泛型。
struct B<'a> {
callback: Option<Box<dyn FnMut() + 'a>>,
}
impl<'a> B<'a> {
fn set_callback(&mut self, callback: Box<dyn FnMut() + 'a>) {
self.callback = Some(callback);
}
fn call_callback(&mut self) {
self.callback.as_mut().map(|cb| cb());
}
}
fn main() {
let mut a = A { x: 0 };
let mut b = B { callback: None };
b.set_callback(Box::new(|| a.do_something()));
b.call_callback();
drop(b); // It is necessary for the code to not use `a` while it's borrowed by the closure
assert_eq!(a.x, 1);
}
您可以通过在结构方法中创建 Box
来获得更多便利,因此调用者不必创建它:
impl<'a> B<'a> {
fn set_callback(&mut self, callback: impl FnMut() + 'a) {
self.callback = Some(Box::new(callback));
}
}