如何将方法作为回调传递 [英] How to pass a method as callback

查看:76
本文介绍了如何将方法作为回调传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python或C ++中,一个类说A可以将一些工作委派给类Say B的另一个实例,并在B中设置A的回调方法。
我试图在Rust中做到这一点,但到目前为止一无所获,被Rust编译器击败。

In Python or C++, a class say A can delegate some work to another instance of class Say B, and set a callback method of A in B. I try to do this in Rust, but so far I got nowhere, beaten by Rust compiler.

这里是我尝试过的代码,其余代码在本文结尾。

Here is Code I have tried, remaining code is at the end of this post.

在A :: test中,我尝试使用闭包获取Fn()特征对象作为回调。

In A::test I tried using closure to get a Fn() trait object as callback.

// let b = B::new(self.finish)); // ideally but would not compile

// let test :Box<Fn(String)> = Box::new(move |msg| {self.finish(msg);}); // cannot infer an appropriate lifetime due to conflicting requirements
// let b = B::new(&test);

// let b = B::new(&Box::new( |msg| {A::finish(&self, msg);} )); // expected trait std::ops::Fn, found closure
// let b = B::new(&Box::new( |msg| {self.finish(msg);} )); // expected trait std::ops::Fn, found closure

尚无任何操作。有办法吗?

Nothing work yet. Is there a way doing this?

任何帮助将不胜感激!

还是我从根本上错了? Rust是否要求其他方法在这里实施该想法?

Or Am I fundamentally wrong? Do Rust request an other way to implement the idea here?

这是我的测试代码

播放地面链接

struct A {}

impl A {
    fn finish(&self, msg: String) {
        println!("{}", msg);
    }

    fn test(&self) {

        //let b = B::new(self.finish)); // would not compile

        // let test :Box<Fn(String)> = Box::new(move |msg| {self.finish(msg);}); // cannot infer an appropriate lifetime due to conflicting requirements
        // let b = B::new(&test);

        // let b = B::new(&Box::new( |msg| {A::finish(&self, msg);} )); // expected trait std::ops::Fn, found closure
        let b = B::new(&Box::new( |msg| {self.finish(msg);} )); // expected trait std::ops::Fn, found closure

        b.start("hi".to_string().clone());
    }
}

struct B<'b> {
    // cb:fn(msg:String),
    cb: &'b Box<Fn(String)>,
}

impl<'b> B<'b> {
    fn new(cb: &'b Box<Fn(String)>) -> B<'b> {
        B { cb: cb }
    }

    fn start(&self, msg: String) {
        (self.cb)(msg);
    }
}

fn main() {
    let a = A {};
    a.test();
}


推荐答案

是的,您可以传递方法作为对您的结构的回调,并从此结构的方法调用它。而且,您无需在传递引用时将封闭框装箱:

Yes you can pass a method as callback to your struct and call it from this struct's method. And you don't need to box the closure as you pass a reference:

struct A {}

impl A {
    fn finish(&self, msg: String) {
        println!("{}", msg);
    }

    fn test(&self) {
        let fun = |msg: String| self.finish(msg);
        let b = B::new(&fun);
        b.start("hi".to_string().clone());
    }
}

struct B<'b> {
    cb: &'b Fn(String),
}

impl<'b> B<'b> {
    fn new(cb: &'b Fn(String)) -> B<'b> {
        B { cb }
    }

    fn start(&self, msg: String) {
        (self.cb)(msg);
    }
}

fn main() {
    let a = A {};
    a.test();
}

游乐场

该框在以下情况下有用

注意,因为函数称为开始,我怀疑在您的实际用例中您想启动一个线程,在这种情况下,您应该查看频道,而不是回调。

Note: As your function is called start, I suspect in your real use case you want to start a thread, in which case you should probably look at channels instead of callbacks.

这篇关于如何将方法作为回调传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆