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

时间:2016-10-23 12:47:58

标签: polymorphism rust

考虑代码:

checkExpression <- function(dataset,str){
    dataset[grepl((str),names(dataset),ignore.case = TRUE)]
}

checkExpression(eatable,"your_string")

这给出了错误:

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>,我们为什么会收到此错误?

2 个答案:

答案 0 :(得分:9)

与大多数在class中嵌入虚拟指针的OO概念语言不同,Rust使用胖指针方法,它将虚拟指针和struct指针并排放在一起。

因此,Box<Trait>的{​​{1}}布局为:

S

在64位平台上为128位。

至于向下转换,目前您可以使用Any类型及其+-------+-------+ | v-ptr | S-ptr | +-------+-------+ downcast_ref

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

答案 1 :(得分:6)

trait object,例如Box<Trait>&Traitcontains two pointers

  • 指向数据的指针
  • 指向 vtable
  • 的指针

两个指针(在64位计算机上)最多可添加128位。

Box<Struct>只包含一个指针,直接指向数据。不需要vtable,因为特定方法可以在编译时静态解析。这个单指针只有64位。

  

鉴于Box<Total>实际上是Box<S>

他们不是。如果他们 相同,他们为什么会有不同的名字? : - )