可以访问结构成员的'TypeId'吗?

ide*_*n42 3 types introspection rust

有没有办法按名称访问struct成员的TypeId(std::any::TypeId::of::<T>)?

如果我有一个基本结构:

MyStruct {
    value: i64,
}
Run Code Online (Sandbox Code Playgroud)

而且我只知道MyStruct并且value,有没有办法访问TypeId::of::<i64>- 哪里i64取决于类型value

main () {
    assert_eq!(
        TypeId::of::<i64>,
        // ^^^ this works
        type_id_of!(MyStruct, value),
        // ^^^ this is what I'm looking for
    );
}
Run Code Online (Sandbox Code Playgroud)

请参阅相关问题:是否可以访问函数签名或声明的结构成员类型?

Mat*_* M. 5

您可以使用类型检测推断出TypeId您拥有的任何值的字段,只要它'static(其他TypeId::of不起作用):

fn type_id<T: 'static + ?Sized>(_: &T) -> TypeId {
    TypeId::of::<T>()
}

fn main() {
    let m = MyStruct { value: 4 };
    println!("{:?} {:?}", TypeId::of::<i64>(), type_id(&m.value));
}
Run Code Online (Sandbox Code Playgroud)

然后,利用offsetof您提出的问题中的策略,您可以创建一个宏来从类型中获取它而不需要实例:

macro_rules! type_id_of {
    ($t:ty, $f:ident) => {
        {
            fn type_of<T: 'static + ?Sized>(_: &T) -> TypeId {
                TypeId::of::<T>()
            }
            let base: $t = unsafe { ::std::mem::uninitialized() };
            let result = type_of(&base.$f);
            ::std::mem::forget(base);
            result
        }
    }
}

fn main() {
    println!("{:?} {:?}", TypeId::of::<i64>(), type_id_of!(MyStruct, value));
}
Run Code Online (Sandbox Code Playgroud)