Types 如何在Rust中打印变量的类型?

Types 如何在Rust中打印变量的类型?,types,rust,Types,Rust,我有以下资料: let mut my_number = 32.90; 如何打印我的\u编号的类型 使用类型和类型无效。是否有其他方法可以打印数字的类型?如果您只想找出变量的类型,并愿意在编译时执行此操作,则可能会导致错误并让编译器将其提取出来 例如: 错误[E0308]:类型不匹配 -->src/main.rs:2:29 | 2 |让mut我的| u编号:()=32.90; |^应为(),找到的是浮点数 | =注意:应为类型“”()` 找到类型`{float}` 或: error[E0599

我有以下资料:

let mut my_number = 32.90;
如何打印
我的\u编号的类型

使用
类型
类型
无效。是否有其他方法可以打印数字的类型?

如果您只想找出变量的类型,并愿意在编译时执行此操作,则可能会导致错误并让编译器将其提取出来

例如:

错误[E0308]:类型不匹配
-->src/main.rs:2:29
|
2 |让mut我的| u编号:()=32.90;
|^应为(),找到的是浮点数
|
=注意:应为类型“”()`
找到类型`{float}`
或:

error[E0599]:在当前作用域中找不到类型为`{float}`的名为`what__this`的方法
-->src/main.rs:3:15
|
我的号码。这是什么;
|               ^^^^^^^^^^^^
或:

error[E0610]:`{float}`是一种基本类型,因此没有字段
-->src/main.rs:3:15
|
我的号码。这是什么
|               ^^^^^^^^^^^^
这些揭示了类型,在这种情况下,实际上并没有完全解决。在第一个示例中称为“浮点变量”,在所有三个示例中称为“
{float}
”;这是一种部分解析的类型,根据您使用它的方式,它可能会以
f32
f64
结束。“
{float}
”不是一个合法的类型名称,它是一个占位符,意思是“我不完全确定这是什么”,但它是一个浮点数。对于浮点变量,如果您不约束它,它将默认为
f64
imk_。(非限定整数文本将默认为
i32

另见:



可能仍然有一些方法会阻碍编译器,使其无法在
f32
f64
之间做出决定;我不确定。它过去像
32.90.eq(&32.90)
一样简单,但现在它把两者都当作
f64
,并且愉快地向前推进,所以我不知道。

UPD以下内容不再有效。检查是否正确

查看
std::intrinsics::get\u tydesc()
。它现在处于“实验”状态,但是如果你只是对类型系统进行黑客攻击也没关系

请查看以下示例:

fn print_type_of<T>(_: &T) -> () {
    let type_name =
        unsafe {
            (*std::intrinsics::get_tydesc::<T>()).name
        };
    println!("{}", type_name);
}

fn main() -> () {
    let mut my_number = 32.90;
    print_type_of(&my_number);       // prints "f64"
    print_type_of(&(vec!(1, 2, 4))); // prints "collections::vec::Vec<int>"
}
fn打印类型(&T)->(){
让我们输入你的名字=
不安全{
(*std::intrinsics::get_tydesc::()).name
};
println!(“{}”,键入_名称);
}
fn main()->(){
让mut my_number=32.90;
打印类型(&my_编号);//打印“f64”
打印类型(&(vec!(1,2,4));//打印“collections::vec::vec”
}

这就是实现著名的
{:?}
格式化程序的方法。

有一个不稳定的函数,可以获取类型名称,尽管您必须使用每晚构建的Rust(这在稳定的Rust中不太可能工作)

#![特征(核心要素)]
fn打印类型(&&T){
println!(“{}”,不安全的{std::intrinsics::type_name::()});
}
fn main(){
打印(&32.90);//打印“f64”
打印(&vec![1,2,4])的类型//打印“std::vec::vec”
打印类型(&“foo”);//打印“&str”
}

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

mod some {
    pub struct SomeType;
}

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


它很脏,但可以工作。

**更新**最近任何时候都没有验证过它可以工作

根据vbo的回答,我放了一个小板条箱来做这件事。它提供一个宏来返回或打印类型

将此文件放入Cargo.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"
}

如果您事先知道所有类型,可以使用traits添加
type\u的
方法:

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

//...
没有intrisic或nothin',因此,尽管更有限,但这是唯一一个可以获得字符串且稳定的解决方案。(请参阅)但是,它非常费劲,并且没有考虑类型参数,因此我们可以

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() };
}
trait-TypeInfo{
fn type_name()->字符串;
(&self)->字符串的fn类型;
}
宏规则!执行类型信息{
($($name:ident$()*),*)=>{
$(impl_type_info_single!($name$()*);)*
};
}
宏规则!mut_if{
($name:ident=$value:expr,$($any:expr)+)=>(让mut$name=$value;);
($name:ident=$value:expr,)=>(让$name=$value;);
}
宏规则!执行类型信息单{
($name:ident$()*)=>{
$name$()*的impl$()*类型信息{
fn type_name()->字符串{
mut_if!(res=String::from(stringify!($name)),$($($T)**);
$(
res.push(“”);
)*
物件
}
(&self)->字符串的类型{
$name$(:)*::键入_name()
}
}
}
}
impl字符串{
让mut res=String::from(&);
res.push_str(&T::type_name());
物件
}
(&self)->字符串的类型{
::键入_name()
}
}
impl字符串{
让mut res=String::from(“&mut”);
res.push_str(&T::type_name());
物件
}
(&self)->字符串的类型{
::键入_name()
}
}
宏规则!类型{
($x:expr)=>{(&$x).type_of()};
}
让我们使用它:

impl_type_info!(i32, i64, f32, f64, str, String, Vec<T>, Result<T,S>)

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!("{}", <Result<String,i64>>::type_name());
    println!("{}", <&i32>::type_name());
    println!("{}", <&str>::type_name());
}
impl\u type\u info!(i32、i64、f32、f64、str、字符串、Vec、结果)
fn main(){
println!(“{}”,第1类);
println!(“{}”,类型为“(&1”);
println!(“{}”,type_of!(&&1));
println!(“{}”,type_of!(&mut1));
println!(“{}”,type_of!(&&mut1));
println!(“{}”,type_of!(&mut&1));
println!(“{}”,type_of!(1.0));
println!(“{}”,类型为!(“abc”);
println!(“{}”,类型为“&”abc”);
println!(“{}”,type_of!(字符串::from(“abc”));
println!(“{}”,type_of!(vec![1,2,3]);
println!(“{},::type_name());
println!(“{},::type_name());
println!(“{}”,::t
#[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"
}
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"
    }
}

//...
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() };
}
impl_type_info!(i32, i64, f32, f64, str, String, Vec<T>, Result<T,S>)

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!("{}", <Result<String,i64>>::type_name());
    println!("{}", <&i32>::type_name());
    println!("{}", <&str>::type_name());
}
[dependencies]
typename = "0.1.1"
fn main() {
    let a = 5.;
    let _: () = unsafe { std::mem::transmute(a) };
}
fn main() {
    let a = 5.;
    unsafe { std::mem::transmute::<_, ()>(a) }
}
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}}
}
use std::any::type_name;

fn type_of<T>(_: T) -> &'static str {
    type_name::<T>()
}

fn main() {
    let str1 = "Rust language";
    let str2 = str1;
    println!("str1 is:  {}, and the type is {}.", str1, type_of(str1));
    println!("str2 is: {}, and the type is {}.", str2, type_of(str2));
    let bool1 = true;
    let bool2 = bool1;
    println!("bool1 is {}, and the type is {}.", bool1, type_of(bool1));
    println!("bool2 is {}, and the type is {}.", bool2, type_of(bool2));
    let x1 = 5;
    let x2 = x1;
    println!("x1 is {}, and the type is {}.", x1, type_of(x1));
    println!("x2 is {}, and the type is {}.", x2, type_of(x2));
    let a1 = 'a';
    let a2 = a1;
    println!("a1 is {}, and the type is {}.", a1, type_of(a1));
    println!("a2 is {}, and the type is {}.", a2, type_of(a2));
    let tup1= ("hello", 5, 'c');
    let tup2 = tup1;
    println!("tup1 is {:?}, and the type is {}.", tup1, type_of(tup1));
    println!("tup2 is {:?}, and the type is {}.", tup2, type_of(tup2));
    let array1: [i32; 3] = [0; 3];
    let array2 = array1;
    println!("array1 is {:?}, and the type is {}.", array1, type_of(array1));
    println!("array2 is {:?}, and the type is {}.", array2, type_of(array2));
    let array: [i32; 5] = [0, 1, 2, 3, 4];
    let slice1 = &array[0..3];
    let slice2 = slice1;
    println!("slice1 is {:?}, and the type is {}.", slice1, type_of(slice1));
    println!("slice2 is {:?}, and the type is {}.", slice2, type_of(slice2));
}
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
[src/main.rs:32] 32.90: f64
[src/main.rs:33] my_number: f64