1、两种枚举
enum枚举和它的方法
1、一个简单的枚举
enum IpAddr{
V4(u32, u32, u32, u32),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 0);
let loopback = IpAddr::V6(String::from("::1"));
2、枚举可以将任意类型的数据放入枚举成员中:例如字符串、数字类型或者结构体,甚至可以包含另一个枚举
3、枚举也有方法
enum Message {
Quit, //Quit 没有关联任何数据
Move { x: i32, y: i32 }, //包含一个匿名结构体。
Write(String),
ChangeColor(i32, i32, i32),
}
impl Message{
fn call(&self){
}
}
Option枚举与空值
空值是一个因为某种原因目前无效或者缺失的值。Rust中没有空值,不过它在标准库中定义了一个可以编码存在或者不存在概念的枚举Option。实现如下:
enum Option<T> {
Some(T),
None,
}
< T>是一个泛型参数,意味着Option枚举的some成员可以包含任意类型的数据。
Option< T>枚举被包含在了prelude中,因此我们不需要将其显示引入作用域就可以直接使用:
fn main() {
let s_string = Some("String");
let x:Option<i8> = Some(5); //存在一个值,而这个值保存在 Some 中
let a_num:Option<i32> = None; //None跟空值具有相同的意义
//Option<T> 和 T(这里 T 可以是任何类型)是不同的类型,编译器不允许像一个肯定有效的值那样使用 Option<T>
let y:i8 = 5; //一般变量,编译器总是能够确保这样的值是有效的
//let sum = x + y; //error[E0369]: binary operation `+` cannot be applied to type `std::option::Option<i8>`。Rust不知道该如果将Option<i8>和i8相加,因为它们的类型不同
}
如果想要使用Option< T>的值,我们必须处理每个成员的代码[可以通过match]:从Some(T)中取出T的值,或者处理None时值为空的情况。不必担心不小心错误的使用了空值
2、枚举与Match
enum与match
#[derive(Debug)] //`derive` only can be applied to structs, enums and unions
enum UsState{
Alibame,
Aliska,
Vermonut,
Cormount,
}
enum Coin{
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin:Coin)->u32{
match coin{
Coin::Penny =>1, //按顺序与每一个分支的模式相比较
Coin::Nickel=>5, //macth会自动穷尽所有的enum值,比如如果删除Coin::Nickel=>5,编译器就会报错
Coin::Dime=>10, //分支代码较短:不使用大括号
Coin::Quarter(state) =>{
println!("Quarter from {:?}", state);
return 25;
}
}
}
fn main() {
let value = value_in_cents(Coin::Quarter(UsState::Alibame));
println!("{}", value);
}
Option< T>与match
fn plus_one(x:Option<i32>)->i32{
match x {
None => -999999,
Some(i) =>i,
}
}
fn main() {
let value = plus_one(Some(5));
println!("{}", value);
}
3、if let语法糖
if let 是 match 的一个语法糖,它当值匹配某一模式时执行代码而忽略所有其他值。
没弄懂用法
参考:https://kaisery.github.io/trpl-zh-cn/ch06-02-match.html