Lesson 14 of 50 · rust
Enums
Duration: 15 minutes
Lesson 14 of 50 · rust
Duration: 15 minutes
rust\nenum Direction {\n North,\n South,\n East,\n West,\n}\n\nfn main() {\n let direction = Direction::North;\n // Use it...\n}\n\n\n## Enums with Associated Data\n\nEnumvariants can carry data:\n\nrust\nenum Message {\n Quit,\n Move { x: i32, y: i32 },\n Write(String),\n ChangeColor(i32, i32, i32),\n}\n\nfn main() {\n let msg1 = Message::Quit;\n let msg2 = Message::Move { x: 5, y: 10 };\n let msg3 = Message::Write(String::from(\"hello\"));\n let msg4 = Message::ChangeColor(255, 0, 0);\n}\n\n\n## Matching Enums\n\nPattern matching with match is how you typically work with enums:\n\nrust\nfn process_direction(dir: Direction) {\n match dir {\n Direction::North => println!(\"Going north!\"),\n Direction::South => println!(\"Going south!\"),\n Direction::East => println!(\"Going east!\"),\n Direction::West => println!(\"Going west!\"),\n }\n}\n\nfn main() {\n process_direction(Direction::North); // Going north!\n}\n\n\nAll variants must be handled.\n\n## Matching with Data\n\nrust\nfn handle_message(msg: Message) {\n match msg {\n Message::Quit => println!(\"Quitting\"),\n Message::Move { x, y } => println!(\"Moving to ({}, {})\", x, y),\n Message::Write(text) => println!(\"Writing: {}\", text),\n Message::ChangeColor(r, g, b) => println!(\"Color: RGB({}, {}, {})\", r, g, b),\n }\n}\n\n\n## The Option Enum\n\nRust provides Option<T> to represent nullable values:\n\nrust\nenum Option<T> {\n Some(T),\n None,\n}\n\n\nIt's so common, you don't need to import it:\n\nrust\nfn divide(a: i32, b: i32) -> Option<i32> {\n if b == 0 {\n None\n } else {\n Some(a / b)\n }\n}\n\nfn main() {\n match divide(10, 2) {\n Some(result) => println!(\"Result: {}\", result),\n None => println!(\"Division by zero!\"),\n }\n}\n\n\n## The Result Enum\n\nFor operations that can fail:\n\nrust\nenum Result<T, E> {\n Ok(T),\n Err(E),\n}\n\n\nrust\nfn parse_number(s: &str) -> Result<i32, std::num::ParseIntError> {\n s.parse()\n}\n\nfn main() {\n match parse_number(\"42\") {\n Ok(n) => println!(\"Number: {}\", n),\n Err(e) => println!(\"Error: {}\", e),\n }\n}\n\n\n## Convenience Methods\n\nOption and Result have useful methods:\n\nrust\nlet x: Option<i32> = Some(5);\nlet y: Option<i32> = None;\n\n// is_some() and is_none()\nif x.is_some() {\n println!(\"x has a value\");\n}\n\n// unwrap() - panics if None\nlet val = x.unwrap(); // 5\n// let bad = y.unwrap(); // panics!\n\n// unwrap_or() - provides default\nlet val2 = y.unwrap_or(0); // 0\n\n// map() - transform the value\nlet doubled = x.map(|n| n * 2); // Some(10)\n\n\n## Practical Example\n\nrust\nenum Status {\n Active,\n Inactive,\n Pending { days_until: u32 },\n}\n\nfn process_status(status: Status) {\n match status {\n Status::Active => println!(\"Ready to go!\"),\n Status::Inactive => println!(\"Offline\"),\n Status::Pending { days_until } => {\n println!(\"Will activate in {} days\", days_until);\n }\n }\n}\n