Module std::any 1.0.0[−][src]
Expand description
该模块实现了 Any
trait,它可以通过运行时反射来动态键入任何 'static
类型。
Any
本身可以用来得到一个 TypeId
,当用作 trait 对象时,它有更多的特性。
作为 &dyn Any
(借用的 trait 对象),它具有 is
和 downcast_ref
方法,以测试所包含的值是否为给定类型,并对该类型的内部值进行引用。
作为 &mut dyn Any
,还有 downcast_mut
方法,用于获取内部值的变量引用。
Box<dyn Any>
添加了 downcast
方法,该方法尝试转换为 Box<T>
。
有关完整的详细信息,请参见 Box
文档。
请注意,&dyn Any
仅限于测试值是否为指定的具体类型,而不能用于测试某个类型是否实现 trait。
智能指针和 dyn Any
将 Any
用作 trait 对象时要记住的一种行为,尤其是对于 Box<dyn Any>
或 Arc<dyn Any>
之类的类型,只需在值上调用 .type_id()
即可生成容器的 TypeId
,而不是底层 trait 对象。
可以通过将智能指针转换为 &dyn Any
来避免,这将返回对象的 TypeId
。
例如:
use std::any::{Any, TypeId};
let boxed: Box<dyn Any> = Box::new(3_i32);
// 您更可能希望这样做:
let actual_id = (&*boxed).type_id();
// ... 比这个:
let boxed_id = boxed.type_id();
assert_eq!(actual_id, TypeId::of::<i32>());
assert_eq!(boxed_id, TypeId::of::<Box<dyn Any>>());
RunExamples
考虑一下我们要注销传递给函数的值的情况。 我们知道我们正在实现的值实现了 Debug,但是我们不知道它的具体类型。我们要对某些类型进行特殊处理:在这种情况下,应先打印 String 值的长度,然后再打印它们的值。 我们在编译时不知道我们值的具体类型,因此我们需要使用运行时反射。
use std::fmt::Debug;
use std::any::Any;
// 用于实现 Debug 的任何类型的 Logger 函数。
fn log<T: Any + Debug>(value: &T) {
let value_any = value as &dyn Any;
// 尝试将我们的值转换为 `String`。
// 如果成功,我们要输出 String 的长度及其值。
// 如果不是,那就是另一种类型:只需将其打印出来即可。
match value_any.downcast_ref::<String>() {
Some(as_string) => {
println!("String ({}): {}", as_string.len(), as_string);
}
None => {
println!("{:?}", value);
}
}
}
// 该函数要先注销其参数,然后再使用它。
fn do_work<T: Any + Debug>(value: &T) {
log(value);
// ... 做一些其他的工作
}
fn main() {
let my_string = "Hello World".to_string();
do_work(&my_string);
let my_i8: i8 = 100;
do_work(&my_i8);
}
RunStructs
TypeId
代表类型的全局唯一标识符。
Traits
一个用来模拟动态类型的 trait。
Functions
以字符串切片的形式返回指向的值的类型的名称。
这与 type_name::<T>()
相同,但是可以在不容易获得变量类型的地方使用。
以字符串切片的形式返回类型的名称。