Important

会合并到基础篇

Diagram

1 DST

use std::mem;
trait Summary {
    fn summarize(&self) -> String;
    fn hello(&self) {
        println!("hello");
    }
}
fn main() {
    // 报错, 无法获取大小
    println!("{}", mem::size_of::<Summary>());
}

2 ZST

use std::mem;
struct Nothing; // No fields = no size
                // All fields have no size = no size
struct LotsOfNothing {
    foo: Nothing,
    qux: (),      // empty tuple has no size
    baz: [u8; 0], // empty array has no size
}

fn main() {
    println!("{}", mem::size_of::<Nothing>());
    println!("{}", mem::size_of::<LotsOfNothing>());
    let a = Nothing {};
    let b = &a;
    println!("{}", mem::size_of_val(&a)); // 0
    println!("{:p}", &a); // 0x7ff7b1bacf4f
    println!("{:p}", &b); // 0x7ff7b1bacf50
    println!("{}", mem::size_of_val(&b)); // 8
}

3 空类型

use std::mem;
enum NoVariants {} // No variants = no size
fn main() {
    // 无法实例化
    // let a = NoVariants;
    println!("{}", mem::size_of::<NoVariants>());
}

4 repr

4.1 repr(C)

它的目的很简单, 就是和 C 保持一致. 数据的顺序,大小,对齐方式都和你在CC++中见到的一摸一样.

我们前面在内存对齐看对Struct A的对齐方式和它的大小,这里我们使用repr(C)来定义Struct A

#[repr(C)]
struct A {
    a: u8,
    b: u32,
    c: u16,
}

use std::mem;
fn main() {
    let x = A { a: 1, b: 2, c: 3 };
    // 12
    println!("{}", mem::size_of_val(&x));
    println!("0x{:p}-0x{:p}-0x{:p}", &x.a, &x.b, &x.c);
}

TODO 特殊情况

  • ZSTs are still zero-sized …

4.2 repr(transparent)

4.3 repr(u) repr(i)

4.4 repr(packed)

Back to top