Rust 语言 Any 特征反射一些例子
Rust
语言是静态系统语言,本身不提供反射功能,但是提供了 Any
Trait,所有类型(含自定义类型)都自动实现了该特征,所以,我们可以通过它进行一些反射技巧。
获取类型限定名(类型 FullName):std::any::type_name
fn main() {
println!("{:?}", std::any::type_name::<String>());
println!("{:?}", std::any::type_name::<i32>());
println!("{:?}", std::any::type_name::<MyType>());
println!("{:?}", std::any::type_name::<MyEnum>());
}
struct MyType {
name: String,
age: u32,
}
enum MyEnum {
One,
}
结果:
"alloc::string::String"
"i32"
"hello::MyType"
"hello::MyEnum"
根据变量反射获取类型限定名:std::any::type_name_of_val
#![feature(type_name_of_val)]
use std::any::type_name_of_val;
fn main() {
let ty = MyType {
name: "Rustln".to_string(),
age: 30,
};
let num = 30;
println!("{:?}", type_name_of_val(&ty));
println!("{:?}", type_name_of_val(&num));
}
struct MyType {
name: String,
age: u32,
}
结果:
"hello::MyType"
"i32"
获取类型全局唯一标识符:std::any::TypeId::of
fn main() {
println!("{:?}", std::any::TypeId::of::<MyType>());
println!("{:?}", std::any::TypeId::of::<i32>());
}
struct MyType {
name: String,
age: u32,
}
结果:
TypeId { t: 8378850550567905954 }
TypeId { t: 3735189839305137790 }
函数接受任意类型参数并打印
use std::{any::Any, fmt::Debug};
fn main() {
let ty = MyType {
name: "Rustln".to_string(),
age: 30,
};
let name = String::from("Rustln");
print_any(&ty);
print_any(&name);
print_any(&30);
}
#[derive(Debug)]
struct MyType {
name: String,
age: u32,
}
fn print_any<T: Any + Debug>(value: &T) {
let value_any = value as &dyn Any;
if let Some(string) = value_any.downcast_ref::<String>() {
println!("String ({}): {}", string.len(), string);
} else if let Some(MyType { name, age }) = value_any.downcast_ref::<MyType>() {
println!("MyType ({}, {})", name, age)
} else {
println!("{:?}", value)
}
}
结果:
MyType (Rustln, 30)
String (6): Rustln
30
判断是否是某类型:std::any::TypeId::is
use std::any::Any;
fn is_string(s: &dyn Any) {
if s.is::<String>() {
println!("It's a string!");
} else {
println!("Not a string...");
}
}
fn main() {
is_string(&0);
is_string(&"cookie monster".to_string());
}
其他例子
use std::any::{type_name, Any};
fn main() {
print_if_string(Box::new(Foo {
age: 30,
name: String::from("Rustln"),
}));
}
fn print_if_string(value: Box<dyn Any>) {
if let Ok(foo) = value.downcast::<Foo>() {
println!("{:?}", &foo)
}
}
#[derive(Debug)]
struct Foo {
name: String,
age: u32,
}
结果:
Foo { name: "Rustln", age: 30 }
通过 stringify!
宏将表达式输出为字符串
let one_plus_one = stringify!(1 + 1);
assert_eq!(one_plus_one, "1 + 1");