Module std::any1.0.0[][src]

Expand description

该模块实现了 Any trait,它可以通过运行时反射来动态键入任何 'static 类型。

Any 本身可以用来获取 TypeId,并用作 trait 对象时具有更多功能。 作为 &dyn Any (借用的 trait 对象),它具有 isdowncast_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>>());
Run

Examples

考虑一下我们要注销传递给函数的值的情况。 我们知道我们正在实现的值实现了 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);
}
Run

Structs

TypeId

TypeId 代表类型的全局唯一标识符。

Traits

Any

trait 来模拟动态类型。

Functions

type_name_of_valExperimental

以字符串切片的形式返回指向的值的类型的名称。 这与 type_name::<T>() 相同,但是可以在不容易获得变量类型的地方使用。

type_name

以字符串切片的形式返回类型的名称。