我想声明一个通用函数,它接受特征对象并且只接受特征对象。我想要这个是因为我想键入删除这些并将它们作为 TraitObject
对象跨 ABI 边界传递。
这样写的函数会编译失败...
fn f<T: ?Sized>(t: &T) -> std::raw::TraitObject {
unsafe { std::mem::transmute(t) }
}
... 出现以下错误:
error[E0512]: transmute called with differently sized types: &T (pointer to T) to std::raw::TraitObject (128 bits)
我理解为什么编译器会提示不同的大小:&T
可以是指向具体类型的指针(如 &i32
),它是单个指针(64 位) ,或特征对象(如 &Display
),这将是两个指针,其布局与 std::raw::TraitObject
(128 位)相同。
只要 &T
是一个特征对象,这个函数就应该没问题,即 T
是一个特征。有没有办法表达这个要求?
最佳答案
不可能证明是否定的...但据我所知,答案是否定的,抱歉。
TraitObject
的表示是不稳定的,特别是因为在未来 Rust 可能能够将多个虚拟指针添加到单个数据指针(表示 &(Display + Eq)
例如)。
与此同时,我通常使用低级内存技巧来读取虚拟指针和数据指针,然后自己构建TraitObject
;通过调用 mem::size_of
来确保 &T
的大小适合 2 *mut ()
因为 ?Sized
表示 Sized
或不是(而不是 !Sized
)。
关于rust - 我可以有一个泛型类型绑定(bind),要求该类型是一个特征吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39922155/