【问题标题】:How to pass a closure via dynamic dispatch in an object-safe method?如何通过对象安全方法中的动态调度传递闭包?
【发布时间】:2020-04-04 02:57:45
【问题描述】:

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

我有 answered this myself,但答案有些不足:FnOnce 闭包必须装箱,因为它们没有大小,必须在使用时消耗(因此不能通过引用传递)。

【问题讨论】:

标签: rust closures traits trait-objects


【解决方案1】:

不用Box也可以通过:

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

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

但是,您将无法在pass_fn_once 中实际调用do_thing,因为它只是借用的 - calling an FnOnce consumes it

如果他们是Boxed,您可以确定pass_fn_once 拥有所有权,以便之后可以丢弃闭包。

【讨论】:

    【解决方案2】:

    FnFnMut 闭包可以通过引用传递,如下所示。 FnOnce 可以通过引用传递,但不能调用,除非它是拥有,例如通过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!")));
    }
    

    【讨论】:

      猜你喜欢
      • 2018-02-26
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 2012-05-20
      • 2023-03-28
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多