2017-02-08 9 views
3

Есть ли способ получить доступ к элементу структуры по имени? TypeId (std::any::TypeId::of::<T>)?Можно получить доступ к 'TypeId' элемента структуры?

Если у меня есть базовая:

-структура
MyStruct { 
    value: i64, 
} 

И я знаю только 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 
    ); 
} 

См родственный вопрос: Is it possible to access the type of a struct member for function signatures or declarations?

+1

Возможно, добавление примера того, как это будет работать, может помочь. Было бы что-то вроде 'TypeId :: of :: '? Обратите внимание: этот синтаксис не существует, но я думаю, что он служит примером того, чего вы пытаетесь достичь. – aochagavia

+1

. Добавлен пример на вопрос – ideasman42

ответ

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

Затем, используя стратегию в 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)); 
} 
+0

Это замечательно! Я не думал, что это будет возможно – aochagavia

+0

@aochagavia: Как только вы знаете, как писать 'offset_of', остальное легко. Это не универсально, потому что 'TypeId :: of' имеет это раздражающее ограничение, что' T' должно быть '' static', но я думаю, что я ничего не могу сделать с этим. –