functions in different keys may have different parameter quantities and types Does this possible in rust?
No. Rust is very statically typed, it doesn't do "fuzzy".
If not, how can I call a function without fuction name(memory address or something)
You can always do that, functions are first class objects in Rust.
You can even unify different functions with the exact same signature through the magic of function pointers (fn()
) or trait objects (dyn Fn()
):
fn main() {
let m0: HashMap<&str, fn(i32, i32) -> i32> = [
("add", (|a, b| a + b) as _),
("sub", (|a, b| a - b) as _),
].into();
dbg!(m0["sub"](1, 2));
let m1: HashMap<&str, Box<dyn Fn(i32, i32) -> i32>> = [
("add", Box::new(|a, b| a + b) as _),
("sub", Box::new(|a, b| a - b) as _),
].into();
dbg!(m1["add"](1, 2));
}
However if you also need variable arities and types, then you need to reify that through additional layers of indirection e.g.
- double-type-erase through double boxing, that requires the least up-front work (just a bunch of casting) but the callsites become pretty gnarly:
let m: HashMap<&str, Box<dyn Any>> = [
("neg", Box::new(Box::new(|a: i32| - a) as Box<dyn Fn(i32) -> i32>) as _),
("add", Box::new(Box::new(|a, b| a + b) as Box<dyn Fn(i32, i32) -> i32>) as _),
].into();
let f = &m["neg"];
if let Some(f) = f.downcast_ref::<Box<dyn Fn(i32) -> i32>>() {
dbg!(f(5));
}
this can be simplified a bit through wrapper types, at the cost of more setup
- an exhaustive enums for all your combinations of parameters and types
- defining all your functions to have the same static interface (e.g. that all of them take an
Args
or Vec<Arg>
which can be dynamically dispatched either internally or externally), possibly through a compatibility layer of macro(s), you might want to limit your input and output types and use something like serde_json::Value
in that case
Other possibilities:
- use a struct rather than a hashmap, then each named slot can have a static type which makes things much easier
- use something like a type map, but that also requires wrapper type (per slot) in order to differentiate slots with the same signature