考虑代码:
use std::boxed::Box;
use std::mem::transmute;
trait Total {
fn total(&self) -> i32;
}
#[derive(Debug)]
struct S {
a: i32,
b: i32,
c: i32,
}
impl S {
fn new() -> S {
S { a: 2, b: 3, c: 4 }
}
}
impl Total for S {
fn total(&self) -> i32 {
self.a + self.b + self.c
}
}
fn main() {
let b: Box<Total> = Box::new(S::new());
unsafe {
let s: Box<S> = std::mem::transmute(b);
println!("S = {:?}", s);
}
}
这给出了错误:
error[E0512]: transmute called with differently sized types: Box<Total> (128 bits) to Box<S> (64 bits)
--> src/main.rs:30:29
|
30 | let s: Box<S> = std::mem::transmute(b);
| ^^^^^^^^^^^^^^^^^^^
鉴于Box<Total>
是真的是一个Box<S>
,为什么我们会收到此错误?
最佳答案
与大多数具有 OO 概念的语言不同,这些语言在 class
中嵌入了虚拟指针, Rust 使用胖指针方法,它同时携带虚拟指针和 struct
彼此并排的指针。
因此,Box<Trait>
的布局对于 S
是:
+-------+-------+
| v-ptr | S-ptr |
+-------+-------+
在 64 位平台上是 128 位。
至于向下转换,目前你可以使用 Any
类型及其 downcast_ref
和 downcast_mut
.
您可能还对 query_interface 感兴趣用于更详细的用例的 crate 。
关于polymorphism - 为什么 Box<trait> 的大小与 Box<struct> 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40203073/