在 Rust 中,枚举(Enum) 是一种定义一组命名值的数据类型。它允许你创建一个可以表示多个不同值的类型,这些值被称为“变体(variants)”。枚举是 Rust 中非常强大的特性之一,广泛用于模式匹配和错误处理。
1.声明一个枚举类型
#[derive(Debug)]
enum Direction {
Up, //上
Down, //下
Left, //左
Right, //右
UpLeft, // 左上
UpRight, // 右上
DownLeft, // 左下
DownRight, // 右下
}
2. 模式匹配match 语法
枚举的目的是对某一类事物的分类,分类的目的是为了对不同的情况进行描述。基于这个原理,往往枚举类最终都会被分支结构处理(许多语言中的 switch )。 switch 语法很经典,但在 Rust 中并不支持,很多语言摒弃 switch 的原因都是因为 switch 容易存在因忘记添加 break 而产生的串接运行问题,Java 和 C# 这类语言通过安全检查杜绝这种情况出现。
Rust 通过 match 语句来实现分支结构。
#[derive(Debug)]
enum Direction {
Up, //上
Down, //下
Left, //左
Right, //右
UpLeft, // 左上
UpRight, // 右上
DownLeft, // 左下
DownRight, // 右下
}
fn main() {
let direction = Direction::UpRight;
match direction {
Direction::Up => println!("向上移动"),
Direction::Down => println!("向下移动"),
Direction::Left => println!("向左移动"),
Direction::Right => println!("向右移动"),
Direction::UpLeft => println!("向左上移动"),
Direction::UpRight => println!("向右上移动"),
Direction::DownLeft => println!("向左下移动"),
Direction::DownRight => println!("向右下移动"),
}
}
运行结果
3.枚举应用主要用于Option 类型和Result 类型
Option枚举类型
Option 是 Rust 标准库中的枚举类型,用于填补 Rust 不支持 null 引用的空白。
许多语言支持 null 的存在(C/C++、Java),这样很方便,但也制造了极大的问题,null 的发明者也承认这一点,"一个方便的想法造成累计 10 亿美元的损失"。
null 经常在开发者把一切都当作不是 null 的时候给予程序致命一击:毕竟只要出现一个这样的错误,程序的运行就要彻底终止。
为了解决这个问题,很多语言默认不允许 null,但在语言层面支持 null 的出现(常在类型前面用 ? 符号修饰)。
Java 默认支持 null,但可以通过 @NotNull 注解限制出现 null,这是一种应付的办法。
Rust 在语言层面彻底不允许空值 null 的存在,但无奈null 可以高效地解决少量的问题,所以 Rust 引入了 Option 枚举类型:
enum Option<T> {
Some(T),
None,
}
具体用法
fn is_null<T: std::fmt::Debug>(opt: Option<T>) {
match opt {
Some(something) => {
println!("{:?}", something);
},
None => {
println!("opt is nothing");
}
}
}
fn main() {
let opt: Option<String> = Option::None;
is_null(opt);
let opt2 = Option::Some("hello");
is_null(opt2);
}
Result 枚举类型
Result 是另一个常用的枚举类型,用于表示操作的成功或失败。Ok(T) 表示成功,Err(E) 表示失败。
enum Result<T, E> {
Ok(T),
Err(E),
}
具体用法
fn main() {
println!("请输入一个整数:");
let mut input = String::new();
std::io::stdin()
.read_line(&mut input)
.expect("读取输入失败");
let n: i32 = match input.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("无效的输入,请输入一个整数!");
return;
}
};
if n < 0 {
println!("n是负数");
}else {
println!("n不9是负数");
}
}
总结一下,Rust的枚举类型非常灵活,能够表示多种不同的情况,每个变体可以携带不同类型和数量的数据。通过模式匹配来处理不同的情况,确保所有可能性都被覆盖。Option和Result是标准库中常用的枚举,用于处理可能缺失的值和错误情况。枚举的方法可以通过impl块定义,使得枚举具有面向对象的一些特性。此外,Rust编译器对枚举的内存布局进行优化,使得枚举在空间上尽可能高效。