Systems
·
v0.0.13
Function pointers
Function pointers exist; closures do not. There is no captured environment to reason about.
Type position
fn(i32, i32) -> i32 // takes two i32, returns i32
fn(*u8) // takes *u8, returns unit
Coercion
A bare function identifier coerces to a function pointer in a position that expects one:
extern fn atexit(cb: fn()) -> i32;
fn cleanup() { println(99); }
fn main() -> i32 {
unsafe { atexit(cleanup); } // bare name coerces
return 0;
}
A struct of callbacks
struct Actions {
on_click: fn(i32) -> i32,
on_hover: fn(i32) -> i32,
}
let a: Actions = Actions { on_click: handle_click, on_hover: handle_hover };
let r: i32 = a.on_click(7); // indirect call through the field
Stateful callbacks: the C convention
Function pointers do not capture environment, so for a callback that needs state, do what C does: pass (fn_ptr, user_data: *u8) and have the library thread user_data back to you unchanged.
extern fn libfoo_subscribe(cb: fn(*u8, i32), user_data: *u8);
This is also how appkit wires UI callbacks: a named function plus an associated object, never a closure.