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