Invoke function by name

I want to pass a variable and two function to a third function, and passed on the variable I'll run either first or second function, like this:

fn third_fn(x: i32, f1: fn(), f2: fn()){
   if /*logic is okc*/ {
      invoke f1
   } else {
     invoke f2
   }
}

// call third_fn as:
third_fn(i, f1, f2)

So I wrote the below function:

fn invoke(f: fn() ) {
    f()
}

So the third_fn became as:

fn third_fn(x: i32, f1: fn(), f2: fn()){
   if /*logic is okc*/ {
      invoke(f1);
   } else {
      invoke(f2);
   }
}

third_fn(i, print_ok, print_error);

fn print_ok(){ println!("ok"); }

fn print_error(){ println!("error"); }

Is the above approach correct? or there is a better way?
I tried to implement a trait so that the function is invoked as f1.invoke() but could not know how to make it, is there a way to make it?

You can just write f1() or f2().

If you want to let the caller pass closures, you could declare the parameters like f1: impl FnOnce() instead, and still call it the same way.

1 Like

The point in the functions passed are passed by names so the '()' is not included, it is something as if it is denied as:

let f1: fn() = print_ok();

// Then want to call f1 as invoke (f1), as I can not have it is f1()

I mean at your call site, try if predicate { f1() } else { f2() } -- this should be perfectly fine even when those are parameters.

1 Like

Understood you now, thanks, but didn't understand your point about trait, can you elaborate more pls.

The argument f1: fn() can only accept regular functions or closures with no captured values. If you allow generic f1: impl FnOnce(), then you can also accept closures with captured state.

let user = get_username();
third_fn(
    x,
    || println!("Hello, {}", user),
    || println!("Goodbye, {}", user),
);
3 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.