Rust – Câu lệnh match

Rate this post

Câu lệnh match có chức năng tương tự với câu lệnh switch trong các ngôn ngữ khác vậy.

Câu lệnh match sẽ kiểm tra xem một biến có giá trị bằng một giá trị nào đó hay không, nếu có thì thực hiện các câu lệnh tương ứng. Cú pháp của câu lệnh match như sau:

match <biến_kiểm_tra> {

<giá_trị> => <câu_lệnh>,

_ => <câu_lệnh>

};

Ví dụ:

fn main() { 
let monthNum: i32 = 4;
match monthNum {
1 => println!("January"),
2 => println!("February"),
3 => println!("March"),
4 => println!("April"),
5 => println!("May"),
6 => println!("June"),
7 => println!("July"),
8 => println!("August"),
9 => println!("September"),
10 => println!("October"),
11 => println!("November"),
12 => println!("December"),
_ => println!("Unknown")
};
}

Trong đoạn code trên chúng ta khai báo biến monthNum có giá trị 4, sau đó chúng ta kiểm tra biến này với câu lệnh match, câu lệnh này sẽ kiểm tra xem giá trị trong biến monthNum giống với giá trị nào trong danh sách, nếu tìm thấy một giá trị giống thì câu lệnh phía sau đó được thực hiện, nếu không giống thì câu lệnh trong giá trị _ sẽ được thực hiện.

April

Giá trị _ giống như giá trị default trong các ngôn ngữ khác, trong Rust thì chúng ta bắt buộc phải có _. Khi câu lệnh match tìm được một giá trị giống với giá trị được kiểm tra thì sẽ thực hiện các câu lệnh phía sau đó rồi dừng luôn chứ không kiểm tra tiếp nữa, do đó ở đây chúng ta không cần câu lệnh break như trong các ngôn ngữ khác.

Câu lệnh match cũng có thể dùng để trả về giá trị, điều kiện là câu lệnh được thực thi cuối cùng trong match phải là một câu lệnh tính toán hoặc có cho ra một giá trị nào đó, ví dụ:

fn main() {
let monthNum: i32 = 9999;
let monthStr: &str = match monthNum {
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December",
_ => "Unknown"
};
println!("{}", monthStr)
}

Để gán giá trị của match thì chúng ta chỉ cần dùng toán tử = là được.

Unknown

Chúng ta cũng có thể kiểm tra trong một khoảng giá trị nếu dùng giá trị kiểu số bằng kí tự ..., ví dụ:

fn main() { 
let mark: f32 = 8.5;
match mark {
8.0…10.0 => println!("Excellent"),
6.5…7.9 => println!("Good"),
5.0…6.4 => println!("Average"),
0.0…4.9 => println!("Poor"),
_ => println!("Cannot grade")
};
}

Excellent

Chúng ta cũng hay dùng match để kiểm tra giá trị của enum, ngoài ra chúng ta cũng có thể dùng toán tử | để kiểm tra nhiều giá trị cùng một lúc, ví dụ:

fn main() {
enum LANG {
Assembly, Scala,
C, Cpp, Rust,
Java, CSharp, Go,
HTML, CSS

let rustLang: LANG = LANG::Rust;
match rustLang {
LANG::Assembly | LANG::Scala => println!("Low level language"),
LANG::C | LANG::Cpp | LANG::Rust => println!("High level language"),
LANG::Java | LANG::CSharp | LANG::Go => println!("Very high level language"),
LANG::HTML | LANG::CSS => println!("Marker language"),
_ => println!("Unknown language")
};
}

High level language

Câu lệnh match cũng rất hay thường được dùng để bắt lỗi, chẳng hạn với các hàm ok().expect() như trong bài trước, ví dụ:

use std::io;
fn main() {
let mut buf = String::new();
println!("Your age: ");
io::stdin().read_line(&mut buf);
let buf_i32: Result<i32, _> = buf.trim().parse();
match buf_i32 {
Ok(i) => println!("Ok, your age in 2017 is {}", 2017 – i),
Err(i) => println!("Error, cannot parse number")
};
println!("Done");
}

Nếu như trong bài trước thì chúng ta gọi hàm ok() rồi tới expect() bình thường, thì nếu chúng ta không nhập vô chữ số mà nhập các kí tự thì Rust sẽ thông báo lỗi, và các câu lệnh sau đó sẽ không được thực thi. Còn trong đoạn code trên, chúng ta kiểm tra xem giá trị trong buf_i32 là một đôi tượng Ok hay là Err, và ứng với mỗi trường hợp chúng ta sẽ thực thi các câu lệnh khác nhau, do đó Rust sẽ không còn báo lỗi nữa và các câu lệnh phía sau vẫn sẽ được thực hiện.

Your age:
phocode.com
Error, cannot parse number
Done
5 1 vote
Article Rating
Subscribe
Thông báo cho tôi qua email khi
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments