1 定义枚举

  • 定义和使用枚举 ``` enum IpAddrKind { V4, V6, }

let four = IpAddrKind::V4; let six = IpAddrKind::V6;

  1. - 在结构体中使用枚举

enum IpAddrKind { V4, V6, }

struct IpAddr { kind: IpAddrKind, address: String, }

fn main() { let home = IpAddr { kind: IpAddrKind::V4, address: String::from(“127.0.0.1”), };

  1. let loopback = IpAddr {
  2. kind: IpAddrKind::V6,
  3. address: String::from("::1"),
  4. };
  5. println!("home={}",home.address);
  6. println!("loop={}",loopback.address);

}

  1. - 更简洁的方式
  2. - 简洁方式1

enum IpAddr { V4(String), V6(String), }

let home = IpAddr::V4(String::from(“127.0.0.1”));

let loopback = IpAddr::V6(String::from(“::1”));

  1. - 简洁方式2

enum IpAddr { V4(u8, u8, u8, u8), V6(String), }

let home = IpAddr::V4(127, 0, 0, 1);

let loopback = IpAddr::V6(String::from(“::1”));

  1. <a name="paFJP"></a>
  2. # 2 Option类型
  3. - Rust没有空值(nil),但std库定义了Option类型,它代表某个值或者None。
  4. - Option类型很有用,所以它被包含在prelude中,不需要显式导入。

enum Option { Some(T), None, }

  1. ```
  2. let some_number = Some(5);
  3. let some_string = Some("a string");
  4. // 这里必须指定类型,仅通过None无法确定Option的类型
  5. let absent_number: Option<i32> = None;
  • Option类型不等于T类型,两者不能进行运算。
  1. let x: i8 = 5;
  2. let y: Option<i8> = Some(5);
  3. let sum = x + y;// 错误: Option<i8>不能与i8进行加法运算
  • 处理Option类型时,必须明确处理值为None(空)的情况。
  • Option的方法(参考https://doc.rust-lang.org/std/option/enum.Option.html)
    • fn is_none(&self) -> bool
    • fn is_some(&self) -> bool
    • fn as_ref(&self) -> Option<&T>
    • fn as_mut(&mut self) -> Option<&mut T>

      3 match 控制流运算符

      3.1 模式匹配```

      enum Coin { Penny, Nickel, Dime, Quarter, }

fn value_in_cents(coin: Coin) -> i32 { match coin { Coin::Penny => { println!(“Lucky penny!”); 1 }, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, } }

  1. <a name="D6Lcv"></a>
  2. ## 3.2 匹配模式的部分值

enum UsState { Alabama, Alaska, // … etc }

fn value_in_cents(coin: Coin) -> i32 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter(state) => { println!(“State quarter from {:?}!”, state); 25 }, } }

  1. <a name="TUeRh"></a>
  2. ## 3.3 对Option类型使用match

fn plus_one(x: Option) -> Option { match x { None => None, Some(i) => Some(i + 1), } }

let five = Some(5); let six = plus_one(five); let none = plus_one(None);

  1. <a name="52RjN"></a>
  2. ## 3.4 必须匹配所有情况

fn plus_one(x: Option) -> Option { match x { Some(i) => Some(i + 1), // 这会通不过编译,因为没有匹配可能的None值 } }

  1. - _作为通配符,类似于default

let someu8_value = 0u8; match some_u8_value { 1 => println!(“one”), 3 => println!(“three”), 5 => println!(“five”), 7 => println!(“seven”), => (), }

  1. <a name="vRVd1"></a>
  2. # 4 if let
  3. <a name="btixm"></a>
  4. ## 4.1 使用match

let someu8_value = Some(0u8); match some_u8_value { Some(3) => println!(“three”), => (), }

  1. <a name="6IKIO"></a>
  2. ## 4.2 使用if let

if let Some(3) = some_u8_value{ println!(“three”); }

  1. <a name="P2zDg"></a>
  2. ## 4.3 带else的if let

let mut count = 0; if let Coin::Quarter(state) = coin { println!(“State quarter from {:?}!”, state); } else { count += 1; }

  1. <a name="9SOep"></a>
  2. # 5 源代码

enum IpAddrKind { V4, V6, }

struct IpAddr { kind: IpAddrKind, address: String, }

[derive(Debug)]

enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32,i32,i32), }

impl Message { fn show(&self){ println!(“my value is: {:?}”,self); } }

fn main() { let home = IpAddr { kind: IpAddrKind::V4, address: String::from(“127.0.0.1”), };

  1. let loopback = IpAddr {
  2. kind: IpAddrKind::V6,
  3. address: String::from("::1"),
  4. };
  5. println!("home={}",home.address);
  6. println!("loop={}",loopback.address);
  7. let msg = Message::Write(String::from("write"));
  8. match msg{
  9. Message::Quit => println!("请求退出"),
  10. Message::Move{x,..} => println!("鼠标移动到: ({},)",x),
  11. Message::Write(str) => println!("控制台输出: {}",str),
  12. Message::ChangeColor(r,..,b) => println!("修改颜色: ({},{})",r,b),
  13. }

} ```