diff --git a/deploy.sh b/deploy.sh index cb6a448..a5207e7 100755 --- a/deploy.sh +++ b/deploy.sh @@ -21,5 +21,5 @@ git remote add origin https://github.com/sunface/rust-by-practice git push -u -f origin gh-pages ## deploy zh-CN -cd ./zh-CN +cd ../zh-CN ./deploy \ No newline at end of file diff --git a/zh-CN/src/compound-types/enum.md b/zh-CN/src/compound-types/enum.md index 298e31d..62dcd2d 100644 --- a/zh-CN/src/compound-types/enum.md +++ b/zh-CN/src/compound-types/enum.md @@ -1 +1,200 @@ -# enum +# 枚举 Enum +🌟🌟 在创建枚举时,你可以使用显式的整数设定枚举成员的值。 + +```rust,editable + +// 修复错误 +enum Number { + Zero, + One, + Two, +} + +enum Number1 { + Zero = 0, + One, + Two, +} + +// C语言风格的枚举定义 +enum Number2 { + Zero = 0.0, + One = 1.0, + Two = 2.0, +} + + +fn main() { + // 通过 `as` 可以将枚举值强转为整数类型 + assert_eq!(Number::One, Number1::One); + assert_eq!(Number1::One, Number2::One); +} +``` + +🌟 枚举成员可以持有各种类型的值 +```rust,editable + +// 填空 +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(i32, i32, i32), +} + +fn main() { + let msg1 = Message::Move{__}; // 使用x = 1, y = 2 来初始化 + let msg2 = Message::Write(__); // 使用 "hello, world!" 来初始化 +} +``` + +🌟🌟🌟 枚举成员中的值可以使用模式匹配来获取 +```rust,editable + +// 仅填空,不要修改其它代码! +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(i32, i32, i32), +} + +fn main() { + let msg = Message::Move{x: 1, y: 1}; + + if let Message::Move{__} = msg { + assert_eq!(x, y); + } + + panic!("不要让这行代码运行!"); +} +``` + +🌟🌟🌟 使用枚举对类型进行同一化 + +```rust,editable + +// 填空,并修复错误 +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(i32, i32, i32), +} + +fn main() { + let msgs: __ = [ + Message::Quit, + Message::Move{x:1, y:3}, + Message::ChangeColor(255,255,0) + ]; + + for msg in msgs { + show_message(msg) + } +} + +fn show_message(msg: Message) { + println!("{}", msg); +} +``` + +🌟🌟 Rust 中没有 `null`,我们通过 `Option` 枚举来处理值为空的情况 +```rust,editable + +// 仅填空,不要修改其它代码! +fn main() { + let five = Some(5); + let six = plus_one(five); + let none = plus_one(None); + + if let __ = six { + println!("{}", n) + } + + panic!("不要让这行代码运行!"); +} + +fn plus_one(x: Option) -> Option { + match x { + __ => None, + __ => Some(i + 1), + } +} +``` + +### 示例 +使用枚举来实现链表. + +```rust,editable + +use crate::List::*; + +enum List { + // Cons: Tuple struct that wraps an element and a pointer to the next node + Cons(u32, Box), + // Nil: A node that signifies the end of the linked list + Nil, +} + +// Methods can be attached to an enum +impl List { + // Create an empty list + fn new() -> List { + // `Nil` has type `List` + Nil + } + + // Consume a list, and return the same list with a new element at its front + fn prepend(self, elem: u32) -> List { + // `Cons` also has type List + Cons(elem, Box::new(self)) + } + + // Return the length of the list + fn len(&self) -> u32 { + // `self` has to be matched, because the behavior of this method + // depends on the variant of `self` + // `self` has type `&List`, and `*self` has type `List`, matching on a + // concrete type `T` is preferred over a match on a reference `&T` + // after Rust 2018 you can use self here and tail (with no ref) below as well, + // rust will infer &s and ref tail. + // See https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/default-match-bindings.html + match *self { + // Can't take ownership of the tail, because `self` is borrowed; + // instead take a reference to the tail + Cons(_, ref tail) => 1 + tail.len(), + // Base Case: An empty list has zero length + Nil => 0 + } + } + + // Return representation of the list as a (heap allocated) string + fn stringify(&self) -> String { + match *self { + Cons(head, ref tail) => { + // `format!` is similar to `print!`, but returns a heap + // allocated string instead of printing to the console + format!("{}, {}", head, tail.stringify()) + }, + Nil => { + format!("Nil") + }, + } + } +} + +fn main() { + // Create an empty linked list + let mut list = List::new(); + + // Prepend some elements + list = list.prepend(1); + list = list.prepend(2); + list = list.prepend(3); + + // Show the final state of the list + println!("linked list has length: {}", list.len()); + println!("{}", list.stringify()); +} +``` \ No newline at end of file