diff --git a/po/zh-CN.po b/po/zh-CN.po index 8d049b5e..e07de8bd 100644 --- a/po/zh-CN.po +++ b/po/zh-CN.po @@ -5382,13 +5382,15 @@ msgstr "" #: src/enums.md:1 msgid "# Enums" -msgstr "" +msgstr "# 枚举" #: src/enums.md:3 msgid "" "The `enum` keyword allows the creation of a type which has a few\n" "different variants:" msgstr "" +"`enum` 关键字允许创建具有几个\n" +"不同变体的类型:" #: src/enums.md:6 msgid "" @@ -5418,7 +5420,7 @@ msgid "" "```" msgstr "" -#: src/enums.md:35 +#: src/enums.md:36 msgid "" "* Enumerations allow you to collect a set of values under one type\n" "* This page offers an enum type `CoinFlip` with two variants `Heads` and " @@ -5431,10 +5433,19 @@ msgid "" "structs but then they wouldn’t be the same type as they would if they were " "all defined in an enum. " msgstr "" +"* 枚举允许你从一种类型下收集一组值\n" +"* 本页提供了一个枚举类型 `CoinFlip`,其中包含 `Heads` 和`Tail`两个变体。在使" +"用变体时,你可能会注意到命名空间。\n" +"* 这可能是比较结构体和枚举的好时机:\n" +" * 在这两者中,你可以获得一个不含字段的简单版本(单位结构体),或一个包含不" +"同类型字段的版本(变体载荷)。\n" +" * 在这两者中,关联的函数都在 `impl` 块中定义。\n" +" * 你甚至可以使用单独的结构体实现枚举的不同变体,但这样一来,如果它们都已在" +"枚举中定义,类型与之前也不一样。" #: src/enums/variant-payloads.md:1 msgid "# Variant Payloads" -msgstr "" +msgstr "# 变体载荷" #: src/enums/variant-payloads.md:3 msgid "" @@ -5442,6 +5453,8 @@ msgid "" "the\n" "`match` statement to extract the data from each variant:" msgstr "" +"你可以定义更丰富的枚举,其中变体会携带数据。然后,你可以使用\n" +"`match` 语句从每个变体中提取数据:" #: src/enums/variant-payloads.md:6 msgid "" @@ -5472,6 +5485,32 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable\n" +"enum WebEvent {\n" +" PageLoad, // Variant without payload\n" +" KeyPress(char), // Tuple struct variant\n" +" Click { x: i64, y: i64 }, // Full struct variant\n" +"}\n" +"\n" +"#[rustfmt::skip]\n" +"fn inspect(event: WebEvent) {\n" +" match event {\n" +" WebEvent::PageLoad => println!(\"page loaded\"),\n" +" WebEvent::KeyPress(c) => println!(\"pressed '{c}'\"),\n" +" WebEvent::Click { x, y } => println!(\"clicked at x={x}, y={y}\"),\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" let load = WebEvent::PageLoad;\n" +" let press = WebEvent::KeyPress('x');\n" +" let click = WebEvent::Click { x: 20, y: 80 };\n" +"\n" +" inspect(load);\n" +" inspect(press);\n" +" inspect(click);\n" +"}\n" +"```" #: src/enums/variant-payloads.md:35 msgid "" @@ -5497,16 +5536,30 @@ msgid "" "cannot implement traits, for example. \n" " " msgstr "" +"* 枚举变体中的值只有在被模式匹配后,才可访问。模式将引用绑定到 `=>` 之后" +"的“match 分支”中的字段。\n" +" * 表达式会从上到下与模式匹配。没有像 C 或 C++ 中那样的跳转。\n" +" * 匹配表达式拥有一个值。值是 match 分支中被执行的最后一个表达式。\n" +" * 从顶部开始,查找与该值匹配的模式,然后沿箭头运行代码。一旦找到匹配,我们" +"便会停止。\n" +"* 展示搜索不详尽时会发生的情况。请注意 Rust 编译器的优势,即确认所有情况何时" +"都得到了处理。\n" +"* `match` 会检查 `enum` 中的隐藏的判别字段。\n" +"* 可以通过调用 `std::mem::discriminant()` 来检索判别\n" +" * 这很有用,例如如果为结构体实现 `PartialEq`,比较字段值不会影响等式。\n" +"* `WebEvent::Click { ... }` 与含顶层 `struct Click { ... }` 的 `WebEvent::" +"Click(Click)` 不完全相同。例如,内嵌版本无法实现 trait。\n" +" " #: src/enums/sizes.md:1 msgid "# Enum Sizes" -msgstr "" +msgstr "# 枚举大小" #: src/enums/sizes.md:3 msgid "" "Rust enums are packed tightly, taking constraints due to alignment into " "account:" -msgstr "" +msgstr "Rust 枚举被紧密地打包,考虑到了对齐的影响,因此存在一些限制:" #: src/enums/sizes.md:5 msgid "" @@ -5530,12 +5583,32 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable\n" +"use std::mem::{align_of, size_of};\n" +"\n" +"macro_rules! dbg_size {\n" +" ($t:ty) => {\n" +" println!(\"{}: size {} bytes, align: {} bytes\",\n" +" stringify!($t), size_of::<$t>(), align_of::<$t>());\n" +" };\n" +"}\n" +"\n" +"enum Foo {\n" +" A,\n" +" B,\n" +"}\n" +"\n" +"fn main() {\n" +" dbg_size!(Foo);\n" +"}\n" +"```" #: src/enums/sizes.md:25 msgid "" "* See the [Rust Reference](https://doc.rust-lang.org/reference/type-layout." "html)." msgstr "" +"* 请参阅 [Rust 引用](https://doc.rust-lang.org/reference/type-layout.html)。" #: src/enums/sizes.md:31 msgid "" @@ -5680,6 +5753,139 @@ msgid "" " }\n" " ```" msgstr "" +" * 在内部,Rust 使用字段(判别)来跟踪枚举变体。\n" +"\n" +" * 你可以根据需要控制判别(例如,与 C 的兼容性):\n" +" \n" +" ```rust,editable\n" +" #[repr(u32)]\n" +" enum Bar {\n" +" A, // 0\n" +" B = 10000,\n" +" C, // 10001\n" +" }\n" +" \n" +" fn main() {\n" +" println!(\"A: {}\", Bar::A as u32);\n" +" println!(\"B: {}\", Bar::B as u32);\n" +" println!(\"C: {}\", Bar::C as u32);\n" +" }\n" +" ```\n" +"\n" +" 如果不使用 `repr`,判别类型会占用 2 个字节,因为 10001 是一个 2\n" +"个字节的数值。\n" +"\n" +"\n" +" * 试试其他类型,例如:\n" +" \n" +" * `dbg_size!(bool)`:大小占用 1 个字节,对齐占用 1 个字节;\n" +" * `dbg_size!(Option)`:大小占用 1 个字节,对齐占用 1 个字节(小众" +"优化,请参阅下文);\n" +" * `dbg_size!(&i32)`:大小占用 8 个字节,对齐占用 8 个字节(在 64 位设备" +"上);\n" +" * `dbg_size!(Option<&i32>)`:大小占用 8 个字节,对齐占用 8 个字节(Null " +"指针优化,请参阅下文)。\n" +"\n" +" * 小众优化:Rust 将对枚举判别合并使用\n" +"未使用的位模式。\n" +"\n" +" * Null 指针优化:对于[某些\n" +"类型](https://doc.rust-lang.org/std/option/#representation),Rust 保证\n" +"`size_of::()` 等效于 `size_of::>()`。\n" +"\n" +" 如果你想展示位表示方式在实践中“可能”会是什么样子,请参考示例代码。\n" +" 请务必注意,编译器对此表示法不提供任何保证,因此这是完全不安全的。\n" +"\n" +" ```rust,editable\n" +" use std::mem::transmute;\n" +"\n" +" macro_rules! dbg_bits {\n" +" ($e:expr, $bit_type:ty) => {\n" +" println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, " +"$bit_type>($e));\n" +" };\n" +" }\n" +"\n" +" fn main() {\n" +" // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n" +" // representation of types.\n" +" unsafe {\n" +" println!(\"Bitwise representation of bool\");\n" +" dbg_bits!(false, u8);\n" +" dbg_bits!(true, u8);\n" +"\n" +" println!(\"Bitwise representation of Option\");\n" +" dbg_bits!(None::, u8);\n" +" dbg_bits!(Some(false), u8);\n" +" dbg_bits!(Some(true), u8);\n" +"\n" +" println!(\"Bitwise representation of Option>\");\n" +" dbg_bits!(Some(Some(false)), u8);\n" +" dbg_bits!(Some(Some(true)), u8);\n" +" dbg_bits!(Some(None::), u8);\n" +" dbg_bits!(None::>, u8);\n" +"\n" +" println!(\"Bitwise representation of Option<&i32>\");\n" +" dbg_bits!(None::<&i32>, usize);\n" +" dbg_bits!(Some(&0i32), usize);\n" +" }\n" +" }\n" +" ```\n" +"\n" +" 如果你想讨论当我们把 256 个以上的 `Option` 串联在一起时会发生什么,可以" +"用更复杂的示例。\n" +"\n" +" ```rust,editable\n" +" #![recursion_limit = \"1000\"]\n" +"\n" +" use std::mem::transmute;\n" +" \n" +" macro_rules! dbg_bits {\n" +" ($e:expr, $bit_type:ty) => {\n" +" println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, " +"$bit_type>($e));\n" +" };\n" +" }\n" +"\n" +" // 用于封装 2^n Some() 中的值的宏,其中 n 的 \"@\" 符号的个数。\n" +" // 增加递归限制需要评估这个宏。\n" +" macro_rules! many_options {\n" +" ($value:expr) => { Some($value) };\n" +" ($value:expr, @) => {\n" +" Some(Some($value))\n" +" };\n" +" ($value:expr, @ $($more:tt)+) => {\n" +" many_options!(many_options!($value, $($more)+), $($more)+)\n" +" };\n" +" }\n" +"\n" +" fn main() {\n" +" // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n" +" // representation of types.\n" +" unsafe {\n" +" assert_eq!(many_options!(false), Some(false));\n" +" assert_eq!(many_options!(false, @), Some(Some(false)));\n" +" assert_eq!(many_options!(false, @@), " +"Some(Some(Some(Some(false)))));\n" +"\n" +" println!(\"Bitwise representation of a chain of 128 Option's." +"\");\n" +" dbg_bits!(many_options!(false, @@@@@@@), u8);\n" +" dbg_bits!(many_options!(true, @@@@@@@), u8);\n" +"\n" +" println!(\"Bitwise representation of a chain of 256 Option's." +"\");\n" +" dbg_bits!(many_options!(false, @@@@@@@@), u16);\n" +" dbg_bits!(many_options!(true, @@@@@@@@), u16);\n" +"\n" +" println!(\"Bitwise representation of a chain of 257 Option's." +"\");\n" +" dbg_bits!(many_options!(Some(false), @@@@@@@@), u16);\n" +" dbg_bits!(many_options!(Some(true), @@@@@@@@), u16);\n" +" dbg_bits!(many_options!(None::, @@@@@@@@), u16);\n" +" }\n" +" }\n" +" ```" #: src/methods.md:3 msgid "" @@ -19571,3 +19777,57 @@ msgid "" "}\n" "```" msgstr "" + +#: src/enums.md:6 +msgid "" +"```rust,editable\n" +"fn generate_random_number() -> i32 {\n" +" // Implementation based on https://xkcd.com/221/\n" +" 4 // Chosen by fair dice roll. Guaranteed to be random.\n" +"}\n" +"\n" +"#[derive(Debug)]\n" +"enum CoinFlip {\n" +" Heads,\n" +" Tails,\n" +"}\n" +"\n" +"fn flip_coin() -> CoinFlip {\n" +" let random_number = generate_random_number();\n" +" if random_number % 2 == 0 {\n" +" return CoinFlip::Heads;\n" +" } else {\n" +" return CoinFlip::Tails;\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" println!(\"You got: {:?}\", flip_coin());\n" +"}\n" +"```" +msgstr "" +"```rust,editable\n" +"fn generate_random_number() -> i32 {\n" +" // Implementation based on https://xkcd.com/221/\n" +" 4 // Chosen by fair dice roll. Guaranteed to be random.\n" +"}\n" +"\n" +"#[derive(Debug)]\n" +"enum CoinFlip {\n" +" Heads,\n" +" Tails,\n" +"}\n" +"\n" +"fn flip_coin() -> CoinFlip {\n" +" let random_number = generate_random_number();\n" +" if random_number % 2 == 0 {\n" +" return CoinFlip::Heads;\n" +" } else {\n" +" return CoinFlip::Tails;\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" println!(\"You got: {:?}\", flip_coin());\n" +"}\n" +"```"