为什么当只需要一个字节时,Rust为什么使用两个字节来表示这个枚举? [英] Why does Rust use two bytes to represent this enum when only one is necessary?
问题描述
即使只有8 * 8 = 64的可能性,似乎仅对A使用一个字节足够聪明,但对B仅使用一个字节不够聪明.有什么办法哄Rust解决这个问题,还是我必须手动实现更紧凑的布局?
It appears to be smart enough to only use one byte for A, but not smart enough to use one byte for B, even though there are only 8*8=64 possibilities. Is there any way to coax Rust to figure this out or do I have to manually implement a more compact layout?
#![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
}
推荐答案
两个字节对于保持借用结构成员的能力都是必需的.
Both bytes are necessary to preserve the ability to borrow struct members.
Rust中的类型不是理想的值集:它具有数据布局,该布局描述了如何存储值.控制该语言的规则"之一是将类型放入struct
或enum
不会改变其数据布局:它在另一种类型内的布局与独立类型的布局相同,这使您可以引用构造成员并与其他任何参考文献互换使用.*
A type in Rust is not an ideal set of values: it has a data layout, which describe how the values are stored. One of the "rules" governing the language is that putting a type inside a struct
or enum
doesn't change its data layout: it has the same layout inside another type as it does standalone, which allows you to take references to struct members and use them interchangeably with any other reference.*
在满足此约束的同时,无法将两个A
装入一个字节,因为A
的大小是一个完整的字节-即使使用repr(packed)
,也无法寻址一个字节的一部分.未使用的位只是保持未使用(除非可以通过利基填充将它们重新用于存储枚举标签).
There's no way to fit two A
s into one byte while satisfying this constraint, because the size of A
is one whole byte -- you can't address a part of a byte, even with repr(packed)
. The unused bits just remain unused (unless they can be repurposed to store the enum tag by niche-filling).
*好吧,repr(packed)
实际上可以使此错误. 引用压缩字段可能导致不确定的行为,即使在安全代码中!
*Well, repr(packed)
can actually make this untrue. Taking a reference to a packed field can cause undefined behavior, even in safe code!
这篇关于为什么当只需要一个字节时,Rust为什么使用两个字节来表示这个枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!