fn main () {
fn1 () ;
}
fn fn1 () {
println! ( " Hello,my name is... { : ? } ", " I don know((( " ) ;
}
I'm assuming that you are referring to the ability to display, or perhaps store, the name of an arbitrary function so that you can use the name as you would a variable.
Support for this technique is made possible through what is known as "runtime reflection". It exists in some programming languages to varying degrees. There is also a concept known as "compile-time reflection", which the reflect crate appears to make work through the usage of macros.
Rust doesn't support runtime reflection. It would be quite difficult, but (perhaps) not impossible, to do what you're trying to do. If you are really interested in doing this, however, you could try implementing something fairly simple such as a container that stores the functions that exist in your program and provides an API to access them as needed.
For example, a naive approach could resemble something like a VTable that contains function pointers mapped to their associated names with the names represented in memory as strings (or whatever type you prefer). This implementation would behave in a similar way as a global HashMap
or similar data structure.
I'm sure someone else will come along and give a more thorough explanation. Hopefully this helps!
It has been suggested a few times, but hasn't come to be so far.
There is a crate or two that supply the name, but I don't know anything about them so use your own judgement.
You can use std::any::type_name()
and the fact that each function is also its own zero-sized type to get the name of a function as long as it's being passed around directly (e.g. by name or via generics) instead of being coerced to a fn()
pointer.
fn main() {
println!("The main function is called {:?}", type_name_of_val(&main));
}
fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
std::any::type_name::<T>()
}
I don't think this is very useful though, seeing as you need to already have a variable/item containing the function and can't just say "what's the current function?" like __func__
in C.
You can do this to some extent at runtime with the backtrace
crate (Rust Playground):
use backtrace::Backtrace;
#[inline(never)]
fn caller_name() -> Option<String> {
let backtrace = Backtrace::new();
let symbol = backtrace
.frames()
.iter()
.flat_map(|frame| frame.symbols())
.nth(1)?;
let name = format!("{}", symbol.name()?);
let name = name.rsplit_once("::")?.0.to_string();
Some(name)
}
But note that it will return None
if the final binary is stripped of its debug symbols.
Should be able to do this with #[track_caller]
and std::panic::Location::caller()
Edit: damn, no, sorry: misread the example. You can get the file name and location, but it is manually providing the failed function name itself in the example.