I found myself implementing this helper trait
trait TypeNameOf {
fn type_name(&self) -> &'static str {
core::any::type_name::<Self>()
}
}
impl<T> TypeNameOf for T {}
and then
dbg!(some_value.type_name());
for debugging because
dbg!(core::any::type_name_of_val(&some_value));
is a little bit ugly.
I can think of 3 approaches to achieve "make it convenient to know types for debugging purposes":
- Impl the above
TypeNameOf
incore::any
(replace thetype_name
call withintrinsics
one of course). - Impl
fn type_name(&self) -> &'static str
incore::any::Any
. I won't recommend this, though it seems reasonable on the surface: what about types that are not'static
? - Impl a declarative macro named
dbg_typeof!
instd
with similar idea (and modified code) withdbg!
:
macro_rules! dbg_typeof {
($val:expr $(,)?) => {
// Use of `match` here is intentional because it affects the lifetimes
// of temporaries - https://stackoverflow.com/a/48732525/1063961
match &$val {
tmp => {
$crate::eprintln!("[{}:{}:{}] typeof({}): {}",
$crate::file!(), $crate::line!(), $crate::column!(), $crate::stringify!($val), core::any::type_name_of_val(tmp));
}
}
};
($($val:expr),+ $(,)?) => {
($($crate::dbg!($val)),+,)
};
}
(The form of the output message can be adjusted)
This is what I preferred because it emphasizes that type_name
is "debug only" and should not be relied upon.