#reflection #meta #introspection #type #metaclass

nightly type-info

编译时和运行时元类型信息和类型反射

3个不稳定版本

使用旧的Rust 2015

0.2.1 2018年4月29日
0.2.0 2018年4月29日
0.1.0 2018年4月26日

#1852 in 数据结构


2 个crate中使用(通过 type-info-derive

MIT 许可证

14KB
170

type-info docs

详细类型信息和反射的实现。

此库提供了在运行时简单访问类型信息的能力,以及操作类型在编译时未知的数据的能力。

有关更多信息,请参阅API文档


lib.rs:

详细类型信息和反射的实现。

此库提供了在运行时简单访问类型信息的能力,以及操作类型在编译时未知的数据的能力。

类型信息

通过派生 TypeInfo 特性,您可以在运行时访问关于类型的类型信息。

#![feature(const_type_id)]

extern crate type_info;
#[macro_use]
extern crate type_info_derive;

use type_info::TypeInfo;

#[derive(TypeInfo)]
struct Person {
    name: String,
    age: u32,
}

fn main() {
    let ty = Person::TYPE;

    assert_eq!("Person", ty.ident);
    assert_eq!(vec!["name", "age"], ty.fields().iter().map(|f| f.ident.unwrap()).collect::<Vec<_>>());
}

静态分发

此示例展示了如何使用带泛型参数的主要 TypeInfo 特性(即不是特性对象)

#
#
// Person is defined like in the above example...

// A function that can take any type that has a field called "name" of type String.
fn add_smith_to_name<A>(anything: &mut A) where A: type_info::TypeInfo {
    let name = anything.field_mut::<String>(type_info::FieldId::Named("name")).unwrap();
    name.push_str(" Smith");
}

fn main() {
    let mut person = Person {
        name: "Lisa".to_owned(),
        age: 23,
    };

    add_smith_to_name(&mut person);

    assert_eq!("Lisa Smith", person.name.as_str());
}

动态分发

此示例展示了当您不想引入类型参数来特化函数,而是更喜欢使用特性对象时,如何使用 DynamicTypeInfo 特性

#
#
// Person is defined like in the above example...

// A function that can take any type that has a field called "name" of type String.
fn add_smith_to_name(anything: &mut type_info::DynamicTypeInfo) {
    let field = anything.field_any_mut(type_info::FieldId::Named("name")).unwrap();
    let name = field.downcast_mut::<String>().unwrap();
    name.push_str(" Smith");
}

fn main() {
    let mut person = Person {
        name: "Lisa".to_owned(),
        age: 23,
    };

    add_smith_to_name(&mut person);

    assert_eq!("Lisa Smith", person.name.as_str());
}

无运行时依赖项