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