如何创建和使用的回调函数列表?(How do I create & use a list of ca

2019-10-22 04:57发布

拉斯特,我试图创建的回调函数后调用列表:

use std::vec::Vec;

fn add_to_vec<T: FnMut() -> ()>(v: &Vec<Box<FnMut() -> ()>>, f: T) {
    v.push(Box::new(f));
}

fn call_b() {
    println!("Call b.");
}

#[test]
fn it_works() {
    let calls: Vec<Box<FnMut() -> ()>> = Vec::new();

    add_to_vec(&calls, || { println!("Call a."); });
    add_to_vec(&calls, call_b);

    for c in calls.drain() {
        c();
    }
}

我主要是以下的建议在这里如何存储关闭 ,但是,我仍然看到一些误区:

src/lib.rs:6:12: 6:23 error: the parameter type `T` may not live long enough [E0311]
src/lib.rs:6     v.push(Box::new(f));
                        ^~~~~~~~~~~
src/lib.rs:6:23: 6:23 help: consider adding an explicit lifetime bound for `T`
src/lib.rs:5:68: 7:2 note: the parameter type `T` must be valid for the anonymous lifetime #1 defined on the block at 5:67...
src/lib.rs:5 fn add_to_vec<T: FnMut() -> ()>(v: &Vec<Box<FnMut() -> ()>>, f: T) {
src/lib.rs:6     v.push(Box::new(f));
src/lib.rs:7 }
src/lib.rs:6:12: 6:23 note: ...so that the type `T` will meet its required lifetime bounds
src/lib.rs:6     v.push(Box::new(f));
                        ^~~~~~~~~~~

我试着改变函数签名:

fn add_to_vec<'a, T: FnMut() -> ()>(v: &Vec<Box<FnMut() -> ()>>, f: &'a T) {

...但是这让我:

src/lib.rs:6:12: 6:23 error: the trait `core::ops::Fn<()>` is not implemented for the type `&T` [E0277]
src/lib.rs:6     v.push(Box::new(f));
                        ^~~~~~~~~~~
error: aborting due to previous error
src/lib.rs:6:12: 6:23 error: the trait `core::ops::Fn<()>` is not implemented for the type `&T` [E0277]
src/lib.rs:6     v.push(Box::new(f));
                        ^~~~~~~~~~~
src/lib.rs:18:24: 18:51 error: mismatched types:
 expected `&_`,
    found `[closure src/lib.rs:18:24: 18:51]`
(expected &-ptr,
    found closure) [E0308]
src/lib.rs:18     add_to_vec(&calls, || { println!("Call a."); });
                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~

(最后的错误我可以通过添加一个正确的& ;而我觉得这是我应该需要的,因为add_to_vec是要最终拥有封闭,因此需要借用它,我不能完全肯定。)

Answer 1:

有你的代码的几个问题。 这里是一个完全固定的版本开始:

use std::vec::Vec;

fn add_to_vec<'a, T: FnMut() + 'a>(v: &mut Vec<Box<FnMut() + 'a>>, f: T) {
    v.push(Box::new(f));
}

fn call_b() {
    println!("Call b.");
}

#[test]
fn it_works() {
    let mut calls: Vec<Box<FnMut()>> = Vec::new();

    add_to_vec(&mut calls, || { println!("Call a."); });
    add_to_vec(&mut calls, call_b);

    for mut c in calls.drain() {
        c();
    }
}

寿命问题是盒装的函数对象必须有一个共同的基础一生; 如果你只写通用约束T: FnMut()它被认为只需要只要函数调用,而不是任何更长的时间才能住。 因此需要添加给它的所有两件事情:通用参数T必须限制到指定的寿命,并以将其存储在矢量内,该性状对象类型必须同样的约束,如Box<FnMut() + 'a> 。 这样,他们既匹配和内存,可确保安全,因此编译器让它通过。 的-> ()的一部分FnMut() -> ()是多余的,通过的方式。

需要进行余下的修补程序是少数的插入mut ; 为了推到向量,你自然需要一个可变的引用,因此&&mut变化,以采取可变引用callsc绑定必须进行mut



文章来源: How do I create & use a list of callback functions?
标签: closures rust