我对《Rust Book》中的这一说法感到困惑:
\n\n\n使用枚举而不是结构还有另一个优点:每个变体可以具有不同类型和数量的关联数据。版本四类型 IP 地址始终有四个数字组成部分,其值介于 0 到 255 之间。如果我们想将 V4 地址存储为四个
\nu8
值,但仍将 V6 地址表示为一个String
值,我们将\xe2\x80\x99t 无法与一个 struct。枚举可以轻松处理这种情况:Run Code Online (Sandbox Code Playgroud)\n#![allow(unused_variables)]\nfn main() {\n enum IpAddr {\n V4(u8, u8, u8, u8),\n V6(String),\n }\n\n let home = IpAddr::V4(127, 0, 0, 1);\n\n let loopback = IpAddr::V6(String::from("::1"));\n}\n
但是,当我尝试使用结构将 V4 地址存储为四个u8
值但仍将 V6 地址表示为一个String
值时,它也执行相同的操作,没有任何错误。
#[derive(Debug)]\nstruct IpAddr {\n V4:(u8, u8, u8, u8),\n V6:String,\n}\n\nfn main () {\n let home = IpAddr {\n V4: (127, 1, 1, 1), \n V6: String::from("Hello"),\n };\n println!("{:#?}", home); \n}\n
Run Code Online (Sandbox Code Playgroud)\n
这是不一样的。所有枚举元素都具有完全相同的大小!枚举元素的大小是最大变体的大小加上变体标识符。
对于结构体来说,情况有点不同。如果我们忽略填充,结构体的大小就是其成员大小的总和。有了填充,它会多一点:
fn main() {
let size = std::mem::size_of::<TheEnum>();
println!("Enum: {}", size * 8);
let size = std::mem::size_of::<TheStruct>();
println!("Struct: {}", size * 8);
}
struct TheStruct {
a: u64,
b: u8,
c: u64
}
enum TheEnum {
A(u64),
B(u8),
C(u64)
}
Run Code Online (Sandbox Code Playgroud)
在这里我们可以看到区别:
枚举:128;64 表示最大变体,64 表示变体标识符。
结构:192;与 64 位对齐,因此我们有 54 位填充
另一个区别在于使用枚举和结构的方式。在枚举中,您只需初始化其中一种变体。根据您的情况 - IPv4 或 IPv6。对于示例中的结构,您必须提供 V4 和 v6 地址。您不能仅提供 V4 或仅提供 V6。
归档时间: |
|
查看次数: |
2284 次 |
最近记录: |