代码之家  ›  专栏  ›  技术社区  ›  Joseph Garvin

当只需要一个字节时,为什么Rust使用两个字节来表示此枚举?

  •  4
  • Joseph Garvin  · 技术社区  · 7 年前

    它似乎足够聪明,可以只为A使用一个字节,但不足以聪明到可以为B使用一个字节,即使只有8*8=64种可能性。有没有办法哄骗Rust解决这个问题,或者我必须手动实现更紧凑的布局?

    Playground link.

    #![allow(dead_code)]
    
    enum A {
        L,
        UL,
        U,
        UR,
        R,
        DR,
        D,
        DL,
    }
    
    enum B {
        C(A, A),
    }
    
    fn main() {
        println!("{:?}", std::mem::size_of::<A>()); // prints 1
        println!("{:?}", std::mem::size_of::<B>()); // prints 2
    }
    
    1 回复  |  直到 7 年前
        1
  •  14
  •   trent oli_obk    7 年前

    这两个字节都是保持借用结构成员能力所必需的。

    Rust中的类型不是一组理想的值:它有一个数据布局,用于描述值的存储方式。管理该语言的“规则”之一是将类型放入 struct enum 不会更改其数据布局:它在另一个类型中的布局与独立类型相同,这允许您获取对结构成员的引用,并将其与任何其他引用互换使用*

    没有办法装两个 A 在满足此约束的同时,将s转换为一个字节,因为 A. repr(packed) . 未使用的位只是保持未使用状态(除非可以通过小生境填充将其重新用于存储枚举标记)。

    *那么, 事实上这是不真实的。 Taking a reference to a packed field can cause undefined behavior ,即使是在安全代码中!