0x01 记录Any
关键字的基本用法
本以为 rust至少也支持java那样的反射机制, 来动态提取一个对象的属性信息(字段+值)
然而, 似乎rust更像scala里的模式匹配, 只能预先知道它是否是一个已知的类型 (静态语言?)
use std::any::{Any, TypeId};
#[derive(Debug)]
enum E { H, He, Li }
struct S { x: u8, y: u8, z: u16 }
fn print_any(a: &Any) {
if let Some(v) = a.downcast_ref::<u32>() {
println!("u32 {}", v);
} else if let Some(v) = a.downcast_ref::<E>() {
println!("enum E {:?}", v);
} else if let Some(v) = a.downcast_ref::<S>() {
println!("struct S {:x} {:x} {:x}", v.x, v.y, v.z);
} else if let Some(v) = a.downcast_ref::<&str>() {
println!("&str {}", v);
} else {
println!("else");
}
}
fn print_string(value: Box<Any>) {
if let Ok(s) = value.downcast::<String>() {
println!("string : {}, with length : {}", s, s.len());
}
else {
println!("Not a string");
}
}
fn main() {
let v1 = 0xc0ffee_u32;
let v2 = E::He;
let v3 = S { x: 0xde, y: 0xad, z: 0xbeef };
let v4 = "rust";
let mut a: &Any;
a = &v1;
println!("{:?}", a.is::<u32>());
println!("{:?}", TypeId::of::<u32>());
a = &v2;
println!("{:?}", a.is::<E>());
println!("{:?}", TypeId::of::<E>());
a = &v3;
println!("{:?}", a.is::<S>());
println!("{:?}", TypeId::of::<S>());
a = &v4;
println!("{:?}", a.is::<&str>());
println!("{:?}", TypeId::of::<&str>());
println!("------------------------------");
print_any(&0xc32_u32);
print_any(&E::Li);
print_any(&S { x: 0x1, y: 0x2, z: 0x3 });
print_any(&10.0_f32);
print_any(&"hoge");
println!("==============================");
let ms = "Hello World".to_string();
print_string(Box::new(ms));
print_string(Box::new(0b110));
}
- 执行结果:
true
TypeId { t: 12849923012446332737 }
true
TypeId { t: 13315273406923548329 }
true
TypeId { t: 10659232371673105595 }
true
TypeId { t: 1229646359891580772 }
------------------------------
u32 3122
enum E Li
struct S 1 2 3
else
&str hoge
==============================
string : Hello World, with length : 11
Not a string