Storing a closure in a HashMap

后端 未结 1 1282
走了就别回头了
走了就别回头了 2021-01-20 17:30

To learn the Rust language, I\'m taking an old C++ library I had lying around and trying to convert it to Rust. It used a lot of C++11 closures and I\'m having some difficul

相关标签:
1条回答
  • 2021-01-20 17:58

    You have taken a &FnMut(&Event)—a trait object—and, after boxing it, wish to store it as a Box<FnMut(&Event)>. Thus, you require that &FnMut(&Event) must implement FnMut(&Event), which it does not (and clearly cannot, for FnMut.call_mut takes &mut self).

    What you wanted was to take an arbitrary type that implements FnMut(&Event)—that is, use generics—and take it by value. The signature is thus this:

    fn make_func<F: FnMut(&Event)>(&mut self, s: &str, f: F)
    

    It gets a little more complex than this due to lifetimes, however, but what you wish to do with regards to that may vary; Storing an unboxed closure with a reference arg in a HashMap has more information on that topic. Here’s what I believe you’re most likely to want:

    struct Object<'a> {
        m_funcs: HashMap<String, Box<FnMut(&Event) + 'a>>,
    }
    
    impl<'a> Object<'a> {
        fn make_func<F: FnMut(&Event) + 'a>(&mut self, s: &str, f: F) {
            self.m_funcs.insert(String::from_str(s), Box::new(f));
        }
    }
    

    You could remove all the 'a in favour of just a single + 'static bound on F if you are happy to not let any of the closures capture references to their environments.

    0 讨论(0)
提交回复
热议问题