我們在前幾天有提到 Result<T, E>
、Option<T>
我們可以用 match
來接錯誤,不過他還有其他的功能
我們可以用 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 的時候要注意型態是否一致,否則會無法編譯
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
就稍微來複習一下吧
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
fn main() {
let number: Result<i32, _> = "123".parse();
match number {
Ok(num) => println!("{}", num),
Err(error) => println!("{}", error),
}
}
結果:
> cargo run
123
而 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 好
最後一行應該是要講 if .. let ?
另外我覺得rust enum的可以附加不同的資料類別還滿好用的。