【问题标题】:Possible to access the 'TypeId' of a struct member?可以访问结构成员的“TypeId”吗?
【发布时间】:2017-02-08 11:14:24
【问题描述】:

有没有办法通过名称访问结构成员的TypeId (std::any::TypeId::of::<T>)?

如果我有一个基本结构:

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?

【问题讨论】:

  • 也许添加一个它如何工作的例子会有所帮助。会不会是 TypeId::of::&lt;MyStruct::value&gt; 之类的东西?请注意,此语法不存在,但我认为它可以作为您尝试实现的示例
  • 向问题添加示例

标签: types rust introspection


【解决方案1】:

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

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

【讨论】:

  • 这太棒了!我不认为这是可能的
  • @aochagavia:一旦你知道如何写offset_of,剩下的就很容易了。虽然它不是通用的,因为 TypeId::of 有这个烦人的限制,即 T 必须是 'static 但我想 对此无能为力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-30
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
相关资源
最近更新 更多