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

后端 未结 11 2133
无人共我
无人共我 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:13

    You can also use the simple approach of using the variable in println!("{:?}", var). If Debug is not implemented for the type, you can see the type in the compiler's error message:

    mod some {
        pub struct SomeType;
    }
    
    fn main() {
        let unknown_var = some::SomeType;
        println!("{:?}", unknown_var);
    }
    

    (playpen)

    It's dirty but it works.

    0 讨论(0)
  • 2020-11-22 09:14

    If you merely wish to find out the type of a variable and are willing to do it at compile time, you can cause an error and get the compiler to pick it up.

    For example, set the variable to a type which doesn't work:

    let mut my_number: () = 32.90;
    // let () = x; would work too
    
    error[E0308]: mismatched types
     --> src/main.rs:2:29
      |
    2 |     let mut my_number: () = 32.90;
      |                             ^^^^^ expected (), found floating-point number
      |
      = note: expected type `()`
                 found type `{float}`
    

    Or call an invalid method:

    let mut my_number = 32.90;
    my_number.what_is_this();
    
    error[E0599]: no method named `what_is_this` found for type `{float}` in the current scope
     --> src/main.rs:3:15
      |
    3 |     my_number.what_is_this();
      |               ^^^^^^^^^^^^
    

    Or access an invalid field:

    let mut my_number = 32.90;
    my_number.what_is_this
    
    error[E0610]: `{float}` is a primitive type and therefore doesn't have fields
     --> src/main.rs:3:15
      |
    3 |     my_number.what_is_this
      |               ^^^^^^^^^^^^
    

    These reveal the type, which in this case is actually not fully resolved. It’s called “floating-point variable” in the first example, and “{float}” in all three examples; this is a partially resolved type which could end up f32 or f64, depending on how you use it. “{float}” is not a legal type name, it’s a placeholder meaning “I’m not completely sure what this is”, but it is a floating-point number. In the case of floating-point variables, if you don't constrain it, it will default to f64¹. (An unqualified integer literal will default to i32.)

    See also:

    • What is the {integer} or {float} in a compiler error message?

    ¹ There may still be ways of baffling the compiler so that it can’t decide between f32 and f64; I’m not sure. It used to be as simple as 32.90.eq(&32.90), but that treats both as f64 now and chugs along happily, so I don’t know.

    0 讨论(0)
  • 2020-11-22 09:15

    You can use the std::any::type_name function. This doesn't need a nightly compiler or an external crate, and the results are quite correct:

    fn print_type_of<T>(_: &T) {
        println!("{}", std::any::type_name::<T>())
    }
    
    fn main() {
        let s = "Hello";
        let i = 42;
    
        print_type_of(&s); // &str
        print_type_of(&i); // i32
        print_type_of(&main); // playground::main
        print_type_of(&print_type_of::<i32>); // playground::print_type_of<i32>
        print_type_of(&{ || "Hi!" }); // playground::main::{{closure}}
    }
    

    Be warned: as said in the documentation, this information must be used for a debug purpose only:

    This is intended for diagnostic use. The exact contents and format of the string are not specified, other than being a best-effort description of the type.

    If you want your type representation to stay the same between compiler versions, you should use a trait, like in the phicr's answer.

    0 讨论(0)
  • 2020-11-22 09:21

    There is an unstable function std::intrinsics::type_name that can get you the name of a type, though you have to use a nightly build of Rust (this is unlikely to ever work in stable Rust). Here’s an example:

    #![feature(core_intrinsics)]
    
    fn print_type_of<T>(_: &T) {
        println!("{}", unsafe { std::intrinsics::type_name::<T>() });
    }
    
    fn main() {
        print_type_of(&32.90);          // prints "f64"
        print_type_of(&vec![1, 2, 4]);  // prints "std::vec::Vec<i32>"
        print_type_of(&"foo");          // prints "&str"
    }
    
    0 讨论(0)
  • 2020-11-22 09:23

    ** UPDATE ** This has not been verified to work any time recently.

    I put together a little crate to do this based off vbo's answer. It gives you a macro to return or print out the type.

    Put this in your Cargo.toml file:

    [dependencies]
    t_bang = "0.1.2"
    

    Then you can use it like so:

    #[macro_use] extern crate t_bang;
    use t_bang::*;
    
    fn main() {
      let x = 5;
      let x_type = t!(x);
      println!("{:?}", x_type);  // prints out: "i32"
      pt!(x);                    // prints out: "i32"
      pt!(5);                    // prints out: "i32"
    }
    
    0 讨论(0)
提交回复
热议问题