polymorphism - 为什么 Box<trait> 的大小与 Box<struct> 不同?

标签 polymorphism rust

考虑代码:

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_refdowncast_mut .

您可能还对 query_interface 感兴趣用于更详细的用例的 crate 。

关于polymorphism - 为什么 Box<trait> 的大小与 Box<struct> 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40203073/

相关文章:

rust - 解决通过引用获取参数的闭包的类型不匹配

c++ - 在多态指针 vector 中搜索特定类型及其子类型

Java 接口(interface) - 参数多态性

c++ - 智能指针和多态

struct - 如何克隆存储盒装特征对象的结构?

rust - 如何使包含 Arc 的结构字段可写?

C++ 二叉树遍历与函数指针参数

c++ - 我可以在 C++ 抽象类中添加什么类型的成员

rust - 为什么初始化向量的向量 (Vec<Vec<T>>) 需要 T 而不是 Vec<T>?

Rust 实现迭代器