IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Rust callback idiom

    金庆发表于 2021-08-24 02:19:00
    love 0
    # Rust callback idiom

    Code is from: https://stackoverflow.com/questions/41081240/idiomatic-callbacks-in-rust
    and
    https://morestina.net/blog/793/closure-lifetimes-in-rust

    ```
    struct Processor<'a> {
        callback: Box<dyn FnMut() + 'a>,
    }

    impl<'a> Processor<'a> {
        fn new() -> Processor<'a> {
            Processor {
                callback: Box::new(|| ()),
            }
        }

        fn set_callback(&mut self, c: impl FnMut() + 'a) {
            self.callback = Box::new(c);
        }

        fn process_events(&mut self) {
            (self.callback)();
        }
    }

    fn simple_callback() {
        println!("hello");
    }

    fn main() {
        let _ = Processor::new();
        
        let mut p = Processor {
            callback: Box::new(simple_callback),
        };
        p.process_events();
        let s = "world!".to_string();
        let callback2 = move || println!("hello {}", s);
        p.set_callback(callback2);
        p.process_events();
    }
    ```

    Note:
    * "impl FnMut()" can only used in function declaration, not in struct declaration.
    * dyn FnMut() is unsized, so it must be stored in Box
    * set_callback(&mut self, c: impl FnMut()) need a lifetime for c to tell compiler that c outlives structure
        + rustc suggests `impl FnMut() + 'static`, but that is too restrictive
            - In most cases, we do not have a static lifetimed callback
    * FnMut() is more restrictive than FnOnce(), but FnOnce() can only be called once
    * set_callback(...) is a template method, because each closure has a different type


    金庆 2021-08-24 10:19 发表评论


沪ICP备19023445号-2号
友情链接