2017-02-08 98 views
3

有沒有辦法按名稱訪問結構成員的TypeIdstd::any::TypeId::of::<T>)?可能訪問結構成員的'TypeId'?

如果我有一個基本的結構:

MyStruct { 
    value: i64, 
} 

只知道MyStructvalue,有沒有訪問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',但我想我沒有辦法做到這一點。 –