2017-02-08 7 views
3

structメンバーのTypeIdstd::any::TypeId::of::<T>)に名前でアクセスする方法はありますか?structメンバーの 'TypeId'にアクセスできますか?

私は基本的な構造体がある場合:

MyStruct { 
    value: i64, 
} 

を私は唯一MyStructvalue知っている、TypeId::of::<i64>にアクセスする方法がある - i64valueの種類に依存するが?

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

関連する質問を参照してください。(他のTypeId::ofが動作しません)あなたがいる限り、それは'staticだとして、あなたが持っている価値の任意のフィールドのTypeIdを推定するタイプの検出を使用することができますIs it possible to access the type of a struct member for function signatures or declarations?

+1

おそらくどのように動作するかの例を追加すると役に立ちます。 'TypeId :: of :: 'のようなものでしょうか?この構文は存在しませんが、私はそれがあなたが達成しようとしているものの例として役立つと思います – aochagavia

+1

質問に追加例 – ideasman42

答えて

5

を:

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 'が ''静的 ''でなければならないという厄介な制限を持っているので、普遍的ではありませんが、私はそれについて何もできません。 –

関連する問題