1

如何将闭包传递给对象安全的 trait 方法或通过动态调度?

我自己已经回答了这个问题,但答案留下了一些不足:FnOnce闭包必须装箱,因为它们没有尺寸并且必须在使用时消耗(因此不能通过引用传递)。

4

2 回答 2

1

您可以在不使用的情况下通过它Box

fn pass_fn_once(do_thing: &dyn FnOnce()) {
    //do_thing();
}

fn main() {
    pass_fn_once(&|| println!("Hello!"));
}

但是,您将无法真正调用do_thingin pass_fn_once,因为它只是借用的 -调用 anFnOnce会消耗它

如果它们被Boxed,您可以确定它pass_fn_once取得了所有权,以便之后可以丢弃关闭。

于 2019-12-10T21:21:53.223 回答
1

FnFnMut闭包可以通过引用传递,如下所示。FnOnce可以通过引用传递但不能调用,除非它是拥有的,例如由 a拥有Box

fn pass_fn(get_num: &dyn Fn() -> i32) {
    let _num = get_num();
}

fn pass_fn_mut(set_num: &mut dyn FnMut(i32)) {
    set_num(6);
}

fn pass_fn_once(do_thing: Box<dyn FnOnce()>) {
    do_thing();
}

fn main() {
    pass_fn(&|| 2);

    let mut x = 1;
    pass_fn_mut(&mut |y| x = y);

    pass_fn_once(Box::new(|| println!("Hello!")));
}
于 2019-12-10T21:40:26.713 回答