2016-10-23 16 views
7

xem xét mã:Tại sao Hộp <trait> có kích thước khác với Hộp <struct>?

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); 
    } 
} 

này cung cấp cho các lỗi:

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); 
    |        ^^^^^^^^^^^^^^^^^^^ 

Cho rằng Box<Total> thực sự là một Box<S>, tại sao chúng ta nhận được lỗi này?

+0

Đã 'để b: Hộp ' ý của bạn là gì? – Aurora0001

+0

Tôi đã xóa [câu hỏi thứ hai và dường như ít quan trọng hơn] (http://meta.stackexchange.com/q/39223/281829). – Shepmaster

Trả lời

9

Không giống như hầu hết các ngôn ngữ có các khái niệm OO nhúng con trỏ ảo trong class, Rust sử dụng cách tiếp cận con trỏ chất béo trong đó nó mang cả con trỏ ảo và con trỏ struct cùng với nhau.

Do vậy, cách bố trí của Box<Trait> cho một S là:

+-------+-------+ 
| v-ptr | S-ptr | 
+-------+-------+ 

đó là 128-bit trên một nền tảng 64-bit.


Đối với downcasting, tại thời điểm này bạn có thể sử dụng các loại Anydowncast_refdowncast_mut của nó.

Bạn cũng có thể quan tâm đến thùng query_interface để biết các trường hợp sử dụng phức tạp hơn.

6

Một trait object, chẳng hạn như Box<Trait> hoặc &Trait, contains two pointers:

  • Một con trỏ đến dữ liệu
  • Một con trỏ tới các vtable

Hai con trỏ (trên máy 64-bit) thêm tối đa 128 bit.

A Box<Struct> chỉ chứa một con trỏ, trực tiếp đến dữ liệu. Không có vtable là cần thiết bởi vì các phương pháp cụ thể có thể được giải quyết tĩnh tại thời gian biên dịch. Con trỏ đơn này chỉ có 64 bit.

Given that Box<Total> is really a Box<S>

Chúng không có. Nếu họ giống nhau, tại sao họ lại có tên khác? :-)

Các vấn đề liên quan