0

I'm trying to pass a callback into a method so my struct can use it later, but I'm getting expected closure, found a different closure with the following code:

struct Struct<T>
    where T: Fn(&[u8])
{
    func: T
}

impl<T> Struct<T>
    where T: Fn(&[u8])
{
    fn set_callback(&mut self, callback: T) {
        self.func = callback;
    }
}

fn main() {
    println!("Hello, world!");

    // this works
    let mut s = Struct {
        func: |msg| {}
    };

    // this doesn't
    s.set_callback(|msg| {});
}
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
anderspitman
  • 9,230
  • 10
  • 40
  • 61
  • If it is the same problem, I'm not quite sure how. That question has to do with storing multiple closures in a Vec, which requires boxing. I'm just trying to store a single closure on a struct. – anderspitman Dec 13 '18 at 06:36
  • Ah ok I think I understand. When I create the Struct, it infers the type and sets it to the closure used there, verifying only that it satisfies the trait constraints. When I try and set it to a different closure later the type is different, regardless of the fact the new one also satisfies the constraints. – anderspitman Dec 13 '18 at 06:50
  • 2
    Right. Also adding, this is more of a general problem and not just related to `Fn*` trait types. [This](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=25c2adc1baa293948b7d3e940c93e245) cousin is easy to understand what's wrong. With `Fn*`types, though they they "seem" identical, the concrete types could capture variables from outside, as a result they have to be unique. The compiler monomorphises `T` to a fixed type. Even if you replace the `set_callback()` with `s.func = |msg| {}` you'd get the same error. `Box` or trait objects solves the problem. – vikram2784 Dec 13 '18 at 07:16

0 Answers0