如何实现TraitId?

时间:2015-05-16 18:25:59

标签: rust

std::any模块包含TypeId。我想实现一个等价的TraitId,这是一种唯一识别特征的方法。

这种实现不需要完全自动化,但如果我可以依赖某些自动化并避免自己归因于ID,那将会更容易。

我的最好"到目前为止的想法是为自己创建一个标记类型,然后在其上实现所有特征(健康滥用panic!())然后使用std::raw::TraitObject从特征表示中获取v-ptr使用 作为我的唯一标识符。

struct Marker;

#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
struct TraitId { id: *mut () }

fn trait_id<T: ?Sized>() -> TraitId
    where Marker: T
{
    let m = Marker { a: 1 };
    let t: &T = &m;
    let id: u64 = unsafe {
        let r: raw::TraitObject = mem::transmute(t);
        mem::transmute(r.vtable)
    };
    TraitId { id: id }
}

这似乎是一个很好的想法,直到(link):

<anon>:14:19: 14:20 error: `T` is not a trait
<anon>:14     where Marker: T
                            ^

有没有人知道如何约束T所以它是一个特征或制作一个(每个特性独特)TraitId

1 个答案:

答案 0 :(得分:2)

滥用TypeId以使TraitId有效。

#![feature(core)]
fn main() {
 println!("{:?}", trait_id::<Clone>());
 println!("{:?}", trait_id::<Sync>());
}

use std::marker::{Reflect};
use std::any::TypeId;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
struct TraitId(TypeId);

fn trait_id<T: ?Sized + Reflect + 'static>() -> TraitId
{
    TraitId(TypeId::of::<T>())
}

Playpen