4

So I'm trying to squeeze in callbacks to this enum variant (Visual) - which will be stored in a vector as seen within the struct EntityComponents:

enum Component {
    Position([f64; 2]),
    Visual(& Fn(Entity) -> ()),
}

struct EntityComponents {
    components_of_entity: HashMap<TypeId, Vec<Component>>,
}

However, Rust requires me to provide explicit lifetime parameters here. My idea is that I want the function reference to live at least as long as its argument (the Entity), but I have no idea how the syntax for that would look like? Is it even possible?

The idea is that as long as an Entity has a Visual component, we can use this callback to render it!

Lii
  • 11,553
  • 8
  • 64
  • 88
Kim
  • 167
  • 1
  • 5
  • Hi Kim, I change the references to code elements in your text to use the customary inline code formatting. I hope your are okay with that! – Lii Aug 22 '17 at 16:33

1 Answers1

4

A few things:

  • You used &Fn() instead of fn(). The former is a trait object of the Fn trait, the latter is a good ol' function pointer. While the former is more general (in particular, it supports closures), it's rather unusual to store a reference to a closure that lives somewhere else.
    • Therefore, if you want to store closures as well, you'd probably use a Box<Fn()> which solves your lifetime problems.
    • If you don't care about closures, but just want to save function pointer, you can simply write Visual(fn(Entity)),. Function pointer always have a static lifetime. So this solves your lifetime problems as well.
    • But what if you really want to store a reference to an Fn trait object, which lives somewhere else? The solution depends on where it lives:
    • In Entity: see here
    • somehere else: use a lifetime <'a>
  • You wrote Fn(Entity) -> (). The -> () is always useless, you can omit it.
Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305