In Rust the fn
keyword can be used to declare a function. But we can also use fn
in a type expression to store function pointers in a vector.
With a vec
of function pointers, we can call functions based on an index. This eliminates the need for a match statement or if-else
chain.
Consider this Rust example program—it has 4 functions declared at the top. In main, we create a Vec
of function pointers.
no_action
" function is used for all 128 indexes. This function could be used to indicate no action is taken.string
"cat" and call the core, art and top functions by the byte
values.fn no_action() -> &'static str { "no action" } fn core() -> &'static str { "core" } fn art() -> &'static str { "art" } fn top() -> &'static str { "top" } fn main() { // Create vector of function pointers. let mut lookup: Vec<fn() -> &'static str> = vec![]; for _ in 0..128 { lookup.push(no_action); } // Store functions as function pointers at specific indexes. lookup[b'c' as usize] = core; lookup[b'a' as usize] = art; lookup[b't' as usize] = top; // Loop over this value and call function for each byte. let value = "cat"; println!("VALUE: {}", value); for c in value.bytes() { println!("RESULT: {}, {}", c as char, lookup[c as usize]()); } }VALUE: cat RESULT: c, core RESULT: a, art RESULT: t, top
It is possible to use a lookup table of function pointers to replace match or if
-statements in Rust. This will affect performance and should be tested.
With a function pointer lookup table, we can develop a simple bytecode interpreter. Each byte
can be handled with a function call based on the byte
value.