原文:https://course.rs/basic/compound-type/enum.html
目录
枚举
⭐️ 枚举类型是一个类型,它会包含所有可能的枚举成员, 而枚举值是该类型中的具体某个成员的实例。
enum PokerCard { Clubs(u8), Spades(u8), Diamonds(char), Hearts(char), } fn main() { let c1 = PokerCard::Spades(5); let c2 = PokerCard::Diamonds('A'); }
enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), } fn main() { let m1 = Message::Quit; let m2 = Message::Move{x:1,y:1}; let m3 = Message::ChangeColor(255,255,0); }
由于每个结构体都有自己的类型,因此我们无法在需要同一类型的地方进行使用,例如某个函数它的功能是接受消息并进行发送,那么用枚举的方式,就可以接收不同的消息,但是用结构体,该函数无法接受 4 个不同的结构体作为参数。
而且从代码规范角度来看,枚举的实现更简洁,代码内聚性更强,不像结构体的实现,分散在各个地方。
Option 处理空值
enum Option<T> { Some(T), None, }
#![allow(unused)] fn main() { fn plus_one(x: Option<i32>) -> Option<i32> { match x { None => None, Some(i) => Some(i + 1), } } let five = Some(5); let six = plus_one(five); let none = plus_one(None); }
枚举实现链表
// 填空,让代码运行 use crate::List::*; enum List { // Cons: 链表中包含有值的节点,节点是元组类型,第一个元素是节点的值,第二个元素是指向下一个节点的指针 Cons(u32, Box<List>), // Nil: 链表中的最后一个节点,用于说明链表的结束 Nil, } // 为枚举实现一些方法 impl List { // 创建空的链表 fn new() -> List { // 因为没有节点,所以直接返回 Nil 节点 // 枚举成员 Nil 的类型是 List Nil } // 在老的链表前面新增一个节点,并返回新的链表 fn prepend(self, elem: u32) -> Self { Cons(elem, Box::new(self)) } // 返回链表的长度 fn len(&self) -> u32 { match *self { // 这里我们不能拿走 tail 的所有权,因此需要获取它的引用 Cons(_, ref tail) => 1 + tail.len(), // 空链表的长度为 0 Nil => 0 } } // 返回链表的字符串表现形式,用于打印输出 fn stringify(&self) -> String { match *self { Cons(head, ref tail) => { // 递归生成字符串 format!("{}, {}", head, tail.stringify()) }, Nil => { format!("Nil") }, } } } fn main() { // 创建一个新的链表(也是空的) let mut list = List::new(); // 添加一些元素 list = list.prepend(1); list = list.prepend(2); list = list.prepend(3); // 打印列表的当前状态 println!("链表的长度是: {}", list.len()); println!("{}", list.stringify()); }