I am trying to understand how to implement a structure with a callback. I succeeded to do it with primitive data types of arguments, but I have a difficult time doing it for compound data types in arguments.
My code:
Your code is saying that the caller of Render::new can decide what type OnUpdate should be but you also force OnUpdate to be the type of a specific closure. You probably want something like dyn Fn( &mut UpdateEvent) rather than OnUpdate.
It's a bit strange but you can be generic on the type of callable. But if you're supporting closures, it's rare to distinguish between the type of callable. You couldn't put the examples in a Vec for instance, as they have different types. You'll monomorphize based on the types in generic contexts. Etc.
I suggest using Box<dyn FnMut> and have Render be not-generic.
Making this closure into a function pointer is possible because it doesn't capture any environment
wait what? I thought closures were sugar for structs+methods.. even if that struct doesn't capture anything, a pointer to that struct is not exactly a pointer to its method?
Or is it that in, say, C terms, because the struct doesn't contain anything the address of the method is the same as the struct itself?
Or should I just not think about it, and tuck away the idea that closures that don't capture their environment can be treated as function pointers because that's just the way it is in Rust?
I would love an IDE plugin that would let me hover over any function (incl closures) and see all the Fn traits (and fn pointer) it can satisfy. Could this one day be done in something like rust-analyzer? Would be an amazing teaching tool too. I find grasping closures to be up there with traits and the borrow checker for difficulty onboarding to Rust
Non-capturing closures are zero-sized structs, so pointer to them doesn't make much sense - they are purely compile-time concept, a type with attached method, which is called everywhere the type is used. And, if something expects function pointer - compiler can automatically use the pointer to this attached method.