我有以下几点:

let mut my_number = 32.90;

如何打印my_number的类型?

使用type和type_of不起作用。有其他方法可以打印数字的类型吗?


当前回答

您还可以使用println中的变量!("{:?}”,var)。如果没有为该类型实现Debug,则可以在编译器的错误消息中看到该类型:

mod some {
    pub struct SomeType;
}

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

(游戏围栏)

虽然很脏,但很管用。

其他回答

短篇小说;

fn tyof<T>(_: &T) -> String {
    std::any::type_name::<T>().into()
}

很长的故事;

trait Type {
    fn type_of(&self) -> String;
}

macro_rules! Type {
    ($($ty:ty),*) => {
        $(
            impl Type for $ty {
                fn type_of(&self) -> String {
                    stringify!($ty).into()
                }
            }
        )*
    }
}

#[rustfmt::skip]
Type!(
    u8, i8, u16, i16, u32, i32, i64, u64, i128, String, [()], (), Vec<()>, &u8, &i8, &u16, &i16, &u32, &i32, &i64, &u64, &i128, &str, &[()], &Vec<()>, &() 
    // add any struct, enum or type you want
);

macro_rules! tyof {
    ($var: expr) => {{
        $var.type_of()
    }};
}

fn main() {
    let x = "Hello world!";
    println!("{}", tyof!(x));
    // or
    println!("{}", x.type_of());

    let x = 5;
    println!("{}", tyof!(x));
    // or
    println!("{}", x.type_of());
}

在稳定rust中有一个@ChrisMorgan答案可以获得近似类型(“float”),在夜间rust中有一个@ShubhamJain答案可以通过不稳定函数获得精确类型(“f64”)。

现在有一种方法可以得到精确的类型(即在f32和f64之间决定)在稳定的rust:

fn main() {
    let a = 5.;
    let _: () = unsafe { std::mem::transmute(a) };
}

结果

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
 --> main.rs:3:27
  |
3 |     let _: () = unsafe { std::mem::transmute(a) };
  |                           ^^^^^^^^^^^^^^^^^^^
  |
  = note: source type: `f64` (64 bits)
  = note: target type: `()` (0 bits)

更新

涡轮鱼的变异

fn main() {
    let a = 5.;
    unsafe { std::mem::transmute::<_, ()>(a) }
}

略短,但可读性稍差。

更新,原始答案如下

trait函数type_name如何,它对于快速获取类型名称非常有用。

pub trait AnyExt {
    fn type_name(&self) -> &'static str;
}

impl<T> AnyExt for T {
    fn type_name(&self) -> &'static str {
        std::any::type_name::<T>()
    }
}

fn main(){
    let my_number = 32.90;
    println!("{}",my_number.type_name());
}

输出:

f64

原来的答案

我写了一个宏type_of!()来调试,它来自std dbg!()。

pub fn type_of2<T>(v: T) -> (&'static str, T) {
    (std::any::type_name::<T>(), v)
}

#[macro_export]
macro_rules! type_of {
    // NOTE: We cannot use `concat!` to make a static string as a format argument
    // of `eprintln!` because `file!` could contain a `{` or
    // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
    // will be malformed.
    () => {
        eprintln!("[{}:{}]", file!(), line!());
    };
    ($val:expr $(,)?) => {
        // Use of `match` here is intentional because it affects the lifetimes
        // of temporaries - https://stackoverflow.com/a/48732525/1063961
        match $val {
            tmp => {
                let (type_,tmp) = $crate::type_of2(tmp);
                eprintln!("[{}:{}] {}: {}",
                    file!(), line!(), stringify!($val), type_);
                tmp
            }
        }
    };
    ($($val:expr),+ $(,)?) => {
        ($($crate::type_of!($val)),+,)
    };
}

fn main(){
    let my_number = type_of!(32.90);
    type_of!(my_number);
}

输出:

[src/main.rs:32] 32.90: f64
[src/main.rs:33] my_number: f64

**更新**最近没有被验证工作。

我把一个小板条箱一起做这个基于vbo的答案。它提供了一个宏来返回或打印类型。

把这个放在你的货物里。toml文件:

[dependencies]
t_bang = "0.1.2"

然后你可以这样使用它:

#[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"
}

你可以使用std::any::type_name函数。这并不需要一个夜间编译器或外部板条箱,结果是非常正确的:

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}}
}

注意:如文档中所述,此信息只能用于调试目的:

这是用于诊断用途。字符串的确切内容和格式没有指定,只是尽力描述该类型。

如果你想让你的类型表示在不同的编译器版本中保持相同,你应该使用一个trait,就像phicr的答案一样。