如何实现 TraitId?

How to implement a TraitId?

std::any 模块包含一个 TypeId。我想实现一个等效的 TraitId,这是唯一标识特征的某种方式。

此实现不必是 "entirely automated",但如果我可以依靠一些自动化并避免自己分配 ID,它会更容易一些。

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

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

滥用 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