iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0

我們在前幾天有提到 Result<T, E>Option<T>

我們可以用 match 來接錯誤,不過他還有其他的功能

variable

我們可以用 match 來判斷變數目前是什麼值,並且做出對應的動作,

就像 if ... else 一樣,不過他可以做更多事情

我們就先來看一下如何用 match 判斷變數

其中 _ 就像是 else 的概念,不適用於上面的,就走 _ 這條

fn main() {
    let x = 2;

    match x {
        1 => println!("x is 1"),
        2 => println!("x is 2"),
        _ => println!("x is something else"),
    }
}

執行後他會走 2 這條

> cargo run

x is 2

那如果 x 不等於 1 或 2 ,應該就會走 _ 這條

fn main() {
    let x = 10;

    match x {
        1 => println!("x is 1"),
        2 => println!("x is 2"),
        _ => println!("x is something else"),
    }
}

結果:

> cargo run

x is something else

但如果我們傳進去的不是 i32 的型態呢?

fn main() {
    let x = 'a';

    match x {
        1 => println!("x is 1"),
        2 => println!("x is 2"),
        _ => println!("x is something else"),
    }
}

編譯時就會噴錯,這邊指的是型態錯誤,x 不符合 match body 中的型態

error[E0308]: mismatched types
 --> src/main.rs:5:9
  |
4 |     match x {
  |           - this expression has type `char`
5 |         1 => println!("x is 1"),
  |         ^ expected `char`, found integer

error[E0308]: mismatched types
 --> src/main.rs:6:9
  |
4 |     match x {
  |           - this expression has type `char`
5 |         1 => println!("x is 1"),
6 |         2 => println!("x is 2"),
  |         ^ expected `char`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `hello_world` (bin "hello_world") due to 2 previous errors

所以在使用 match 的時候要注意型態是否一致,否則會無法編譯

enum

match 還可以使用在 enum 上,

Rust 中的 enum 指的是一種型態,跟我之前學習的 Rails 的 enum 不太一樣

Rust 的 enum 可以塞許多的值,而且他們的型態可以是不一樣的

我們可以來判斷這個變數是符合 enum 中哪個值

fn main() {
    enum Friend {
        Amy,
        Jack,
        Yui,
    };

    let my_friend = Friend::Amy;

    match my_friend {
        Friend::Amy => println!("My friend is Amy"),
        Friend::Jack => println!("My friend is Jack"),
        Friend::Yui => println!("My friend is Yui"),
    }
}

當執行後

> cargo run

My friend is Amy

但如果變數是指向 enum 中沒有的值呢?

fn main() {
    enum Friend {
        Amy,
        Jack,
        Yui,
    };

    let my_friend = Friend::Ann;

    match my_friend {
        Friend::Amy => println!("My friend is Amy"),
        Friend::Jack => println!("My friend is Jack"),
        Friend::Yui => println!("My friend is Yui"),
        _ => println!("I don't have friend"),
    }
}

他就會說在 Enum 中找不到 Ann

> cargo run

error[E0599]: no variant or associated item named `Ann` found for enum `Friend` in the current scope
 --> src/main.rs:8:29
  |
2 |     enum Friend {
  |     ----------- variant or associated item `Ann` not found for this enum
...
8 |     let my_friend = Friend::Ann;
  |                             ^^^ variant or associated item not found in `Friend`

For more information about this error, try `rustc --explain E0599`.
warning: `hello_world` (bin "hello_world") generated 1 warning
error: could not compile `hello_world` (bin "hello_world") due to previous error; 1 warning emitted

所以用 match 其實要知道目前這個變數的值是否有符合你比對的任意值,

如果型態錯誤,或者沒有對應值,就會無法編譯!

Option / Result

接下來是我們之前提到的 Option 及 Result

就稍微來複習一下吧

Option

fn main() {
    let my_name: Option<&str> = Some("Ning");

    match my_name {
        Some(name) => println!("My name is {}", name),
        None => println!("I don't have name :("),
    }
}

結果:

> cargo run

My name is Ning

Result

fn main() {
    let number: Result<i32, _> = "123".parse();

    match number {
        Ok(num) => println!("{}", num),
        Err(error) => println!("{}", error),
    }
}

結果:

> cargo run

123

if let

而 match 也可以用 if let 來代替唷!不過用法會不一樣,還需要搭配 if ... else

fn main() {
    let my_name: Option<&str> = Some("Ning");

    if let Some(name) = my_name {
        println!("My name is {}", name)
    } else {
        println!("I don't have name :(")
    }
}

match 跟 if...else 其實蠻相似的,不過 match 還會進行 type 的比對,並且易讀性也相較 if ... else 好


上一篇
Day 12 Macro
下一篇
Day 14 Trait & Derive
系列文
成為程式界的 F1 賽車手,用 30 天認識 Rust 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Hell Kiki
iT邦新手 4 級 ‧ 2023-09-28 12:23:45

最後一行應該是要講 if .. let ?

另外我覺得rust enum的可以附加不同的資料類別還滿好用的。

我要留言

立即登入留言