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:
std::reflect
std::repr
None of these give me enough to go on to get started. How would I implement the function I describe above?
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.
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.
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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With