How do I print the type of a variable in Rust?

后端 未结 11 2266
无人共我
无人共我 2020-11-22 08:49

I have the following:

let mut my_number = 32.90;

How do I print the type of my_number?

Using type and

11条回答
  •  清歌不尽
    2020-11-22 09:12

    If you know all the types beforehand, you can use traits to add a type_of method:

    trait TypeInfo {
        fn type_of(&self) -> &'static str;
    }
    
    impl TypeInfo for i32 {
        fn type_of(&self) -> &'static str {
            "i32"
        }
    }
    
    impl TypeInfo for i64 {
        fn type_of(&self) -> &'static str {
            "i64"
        }
    }
    
    //...
    

    No intrisics or nothin', so although more limited this is the only solution here that gets you a string and is stable. (see French Boiethios's answer) However, it's very laborious and doesn't account for type parameters, so we could...

    trait TypeInfo {
        fn type_name() -> String;
        fn type_of(&self) -> String;
    }
    
    macro_rules! impl_type_info {
        ($($name:ident$(<$($T:ident),+>)*),*) => {
            $(impl_type_info_single!($name$(<$($T),*>)*);)*
        };
    }
    
    macro_rules! mut_if {
        ($name:ident = $value:expr, $($any:expr)+) => (let mut $name = $value;);
        ($name:ident = $value:expr,) => (let $name = $value;);
    }
    
    macro_rules! impl_type_info_single {
        ($name:ident$(<$($T:ident),+>)*) => {
            impl$(<$($T: TypeInfo),*>)* TypeInfo for $name$(<$($T),*>)* {
                fn type_name() -> String {
                    mut_if!(res = String::from(stringify!($name)), $($($T)*)*);
                    $(
                        res.push('<');
                        $(
                            res.push_str(&$T::type_name());
                            res.push(',');
                        )*
                        res.pop();
                        res.push('>');
                    )*
                    res
                }
                fn type_of(&self) -> String {
                    $name$(::<$($T),*>)*::type_name()
                }
            }
        }
    }
    
    impl<'a, T: TypeInfo + ?Sized> TypeInfo for &'a T {
        fn type_name() -> String {
            let mut res = String::from("&");
            res.push_str(&T::type_name());
            res
        }
        fn type_of(&self) -> String {
            <&T>::type_name()
        }
    }
    
    impl<'a, T: TypeInfo + ?Sized> TypeInfo for &'a mut T {
        fn type_name() -> String {
            let mut res = String::from("&mut ");
            res.push_str(&T::type_name());
            res
        }
        fn type_of(&self) -> String {
            <&mut T>::type_name()
        }
    }
    
    macro_rules! type_of {
        ($x:expr) => { (&$x).type_of() };
    }
    

    Let's use it:

    impl_type_info!(i32, i64, f32, f64, str, String, Vec, Result)
    
    fn main() {
        println!("{}", type_of!(1));
        println!("{}", type_of!(&1));
        println!("{}", type_of!(&&1));
        println!("{}", type_of!(&mut 1));
        println!("{}", type_of!(&&mut 1));
        println!("{}", type_of!(&mut &1));
        println!("{}", type_of!(1.0));
        println!("{}", type_of!("abc"));
        println!("{}", type_of!(&"abc"));
        println!("{}", type_of!(String::from("abc")));
        println!("{}", type_of!(vec![1,2,3]));
    
        println!("{}", >::type_name());
        println!("{}", <&i32>::type_name());
        println!("{}", <&str>::type_name());
    }
    

    output:

    i32
    &i32
    &&i32
    &mut i32
    &&mut i32
    &mut &i32
    f64
    &str
    &&str
    String
    Vec
    Result
    &i32
    &str
    

    Rust Playground

提交回复
热议问题