Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I invoke an unknown Rust function with some arguments using reflection?

I'm having a lot of fun playing around with Rust having been a C# programmer for a long time but I have a question around reflection. Maybe I don't need reflection in this case but given that Rust is strongly typed I suspect I do (I would definitely need it in good ol' C#, bless its cotton socks).

I have this situation:

use std::collections::HashMap;

fn invoke_an_unknown_function(
    hashmap: HashMap<String, String>,
    // Something to denote a function I know nothing about goes here
) {
    // For each key in the hash map, assign the value
    // to the parameter argument whose name is the key
    // and then invoke the function
}

How would I do that? I'm guessing I need to pass in some sort of MethodInfo as the second argument to the function and then poke around with that to get the arguments whose name is the key in the hash map and assign the values but I had a look around for the reflection API and found the following pre-Rust 1.0 documentation:

  • Module std::reflect
  • Module std::repr
  • [rust-dev] Reflection system

None of these give me enough to go on to get started. How would I implement the function I describe above?

like image 585
kmp Avatar asked Dec 07 '13 20:12

kmp


People also ask

How do you call a function in Rust?

We define a function in Rust by entering fn followed by a function name and a set of parentheses. The curly brackets tell the compiler where the function body begins and ends. We can call any function we've defined by entering its name followed by a set of parentheses.

Does Rust have reflection?

First of all, Rust doesn't have reflection; reflection implies you can get details about a type at runtime, like the fields, methods, interfaces it implements, etc. You can not do this with Rust.

How to return closures Rust?

Closures are represented by traits, which means you can't return closures directly. In most cases where you might want to return a trait, you can instead use the concrete type that implements the trait as the return value of the function.


1 Answers

Traits are the expected way to implement a fair amount of what reflection is (ab)used for elsewhere.

trait SomeInterface {
    fn exposed1(&self, a: &str) -> bool;
    fn exposed2(&self, b: i32) -> i32;
}

struct Implementation1 {
    value: i32,
    has_foo: bool,
}

impl SomeInterface for Implementation1 {
    fn exposed1(&self, _a: &str) -> bool {
        self.has_foo
    }

    fn exposed2(&self, b: i32) -> i32 {
        self.value * b
    }
}

fn test_interface(obj: &dyn SomeInterface) {
    println!("{}", obj.exposed2(3));
}

fn main() {
    let impl1 = Implementation1 {
        value: 1,
        has_foo: false,
    };
    test_interface(&impl1);
}
like image 143
Sean Perry Avatar answered Sep 21 '22 18:09

Sean Perry