在这段代码中,我获取一个向量,创建一个结构实例,并将它添加到装箱的向量中:
trait T {}
struct X {}
impl T for X {}
fn add_inst(vec: &mut Vec<Box<T>>) -> &X {
let x = X {};
vec.push(Box::new(x));
// Ugly, unsafe hack I made
unsafe { std::mem::transmute(&**vec.last().unwrap()) }
}
显然,它使用了 mem::transmute
,这让我觉得这不是正确的方法。这个丑陋的 hack 是唯一的方法吗?
此外,虽然它在 Rust 1.32 中编译,但在 Rust 1.34 中失败:
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> src/lib.rs:10:14
|
10 | unsafe { std::mem::transmute(&**vec.last().unwrap()) }
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `&dyn T` (128 bits)
= note: target type: `&X` (64 bits)
最佳答案
我认为这段代码是安全的:
fn add_inst(vec: &mut Vec<Box<dyn T>>) -> &X {
let x = X {};
let b = Box::new(x);
let ptr = &*b as *const X;
vec.push(b);
unsafe { &*ptr }
}
诀窍是将原始指针保存到*const X
在将其转换为 Box<dyn T>
之前.然后您可以在从函数返回之前将其转换回引用。
这是安全的,因为装箱的值永远不会移动(当然,除非它移出 Box
),所以 ptr
在 b
的 Actor 阵容中幸存下来进入Box<dyn T>
.
关于vector - 如何返回对添加到特征对象向量的具体类型的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55784587/