Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to access the 'TypeId' of a struct member?

Is there a way to access the TypeId (std::any::TypeId::of::<T>) of a struct member by name?

If I have a basic struct:

MyStruct {
    value: i64,
}

And I only know MyStruct and value, is there a way to access TypeId::of::<i64> - where i64 depends on the type of value?

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

See related question: Is it possible to access the type of a struct member for function signatures or declarations?

like image 840
ideasman42 Avatar asked Oct 21 '25 05:10

ideasman42


1 Answers

You can use type detection to deduce the TypeId of any field of a value you have, as long as it's 'static (other TypeId::of doesn't work):

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));
}

Then, leveraging the strategy in the offsetof question you asked, you can make a macro to get it from a type without having an instance:

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));
}
like image 136
Matthieu M. Avatar answered Oct 24 '25 13:10

Matthieu M.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!