rust - 我可以有一个泛型类型绑定(bind),要求该类型是一个特征吗?

标签 rust

我想声明一个通用函数,它接受特征对象并且只接受特征对象。我想要这个是因为我想键入删除这些并将它们作为 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/

相关文章:

rust - 为什么 Rust 在构造 nalgebra::MatrixN 时无法找出要使用的正确 `from_iterator`?

rust - 使用no_std进行的 cargo 测试失败,错误代码为176、160

linux - 启动一个 rust 二进制文件作为 systemd 守护进程

rust - 如何获取配置标志的值?

rust - 创建特征对象的副本

io - 读取字节时填充用户提供的缓冲区的惯用方法是什么?

rust - 将克隆添加到防 rust 液体模板

algorithm - 如何迭代生成 de Bruijn 序列?

rust - 在 rust 中使用 u32 整数类型

winapi - Rust 中的 Win32 OpenGL 窗口 : unable to load certain function pointers