Bỏ qua để đến nội dung

Toán tử trong Rust

Toán tử (operator) là những ký hiệu bạn dùng để làm toán, so sánh giá trị và kết hợp các điều kiện. Phần lớn chúng sẽ trông quen thuộc nếu bạn từng dùng một ngôn ngữ giống C.

fn main() {
let a = 10;
let b = 3;
println!("{}", a + b); // 13
println!("{}", a - b); // 7
println!("{}", a * b); // 30
println!("{}", a / b); // 3 (chia số nguyên, bỏ phần dư)
println!("{}", a % b); // 1 (phần dư)
}
▶ Tự chạy thử

Những toán tử này so sánh hai giá trị và trả lại một bool:

fn main() {
let a = 5;
let b = 8;
println!("{}", a == b); // false
println!("{}", a != b); // true
println!("{}", a < b); // true
println!("{}", a > b); // false
println!("{}", a <= b); // true
println!("{}", a >= b); // false
}

Bạn sẽ dùng chúng liên tục trong các điều kiện if, thứ chúng ta sẽ học ở bài If…else.

Toán tử logic kết hợp hoặc đảo ngược các giá trị boolean:

fn main() {
let is_logged_in = true;
let is_admin = false;
println!("{}", is_logged_in && is_admin); // false — cả hai phải là true
println!("{}", is_logged_in || is_admin); // true — ít nhất một cái là true
println!("{}", !is_admin); // true — đảo false thành true
}
▶ Tự chạy thử
  • && — và (and): chỉ đúng khi cả hai vế đều đúng.
  • || — hoặc (or): đúng nếu ít nhất một vế đúng.
  • ! — không (not): đảo đúng thành sai và ngược lại.

Ngoài dấu = thông thường, Rust có các toán tử viết tắt để cập nhật một biến dựa trên giá trị hiện tại của nó:

fn main() {
let mut score = 10;
score += 5; // giống như: score = score + 5
score -= 2; // score = score - 2
score *= 3; // score = score * 3
score /= 2; // score = score / 2
println!("{score}");
}
▶ Tự chạy thử

Hãy nhớ rằng biến phải có mut thì những dòng này mới biên dịch được — vì bạn đang thay đổi giá trị của nó.

Khi một biểu thức có nhiều toán tử, Rust không chỉ đơn giản đi từ trái sang phải. Giống như toán ở trường, *, / và % được tính trước + và -. Các toán tử cùng cấp được tính từ trái sang phải. Dấu ngoặc đơn luôn được tính trước tiên, nên hãy dùng chúng bất cứ khi nào bạn muốn một thứ tự khác.

fn main() {
let a = 2 + 3 * 4; // * trước: 2 + 12
let b = (2 + 3) * 4; // ngoặc trước: 5 * 4
let c = 10 - 4 - 3; // cùng cấp, trái sang phải: (10 - 4) - 3
let d = 17 % 5 * 2; // cùng cấp, trái sang phải: (17 % 5) * 2
let ok = 1 + 1 == 2 && 3 > 2; // tính toán, rồi so sánh, rồi &&
println!("{a} {b} {c} {d} {ok}");
}

Kết quả:

14 20 3 4 true
▶ Tự chạy thử

Thứ tự đầy đủ, từ trước đến sau, đại khái là: số học (* / %, rồi + -), sau đó so sánh (== != < > <= >=), rồi &&, rồi ||, và cuối cùng là các toán tử gán (= += -= và những người anh em). Đó là lý do 1 + 1 == 2 && 3 > 2 chạy được mà không cần dấu ngoặc nào. Dù vậy, nếu bạn phải dừng lại suy nghĩ về thứ tự, hãy thêm dấu ngoặc. Chúng chẳng tốn gì mà còn giúp code dễ đọc hơn.

Một video dài 125 giây. Lưu con số đó vào một biến, rồi in ra nó bằng bao nhiêu phút tròn và bao nhiêu giây lẻ, như 2 phút 5 giây. Gợi ý: phép chia số nguyên / cho số phút tròn, còn % cho phần còn dư.

Xem lời giải
fn main() {
let total_seconds = 125;
let minutes = total_seconds / 60; // 2 (phần dư bị bỏ đi)
let seconds = total_seconds % 60; // 5 (phần dư)
println!("{minutes} phút {seconds} giây");
}

Kết quả:

2 phút 5 giây
▶ Tự chạy thử

Bắt đầu biến score của một trò chơi ở 10. Cộng 25, trừ 5, rồi nhân đôi, bằng các toán tử gán viết tắt. In ra điểm số, xem nó có ít nhất 50 không, và xem nó có ít nhất 50 và là số chẵn không. Gợi ý: một số là số chẵn khi score % 2 == 0.

Xem lời giải
fn main() {
let mut score = 10;
score += 25; // 35
score -= 5; // 30
score *= 2; // 60
println!("điểm: {score}");
println!("qua màn chưa? {}", score >= 50);
println!("qua màn và là số chẵn? {}", score >= 50 && score % 2 == 0);
}

Kết quả:

điểm: 60
qua màn chưa? true
qua màn và là số chẵn? true
▶ Tự chạy thử
  • Số học: + - * / %. Phép chia số nguyên cắt bỏ phần lẻ — không có số thập phân.
  • So sánh: == != < > <= >=, tất cả đều trả về một bool.
  • Logic: && (và), || (hoặc), ! (không).
  • Gán viết tắt: += -= *= /= cập nhật trực tiếp một biến mut. Không có ++.
  • * / % được tính trước + -, và phép tính số học được tính trước so sánh và &&/||. Khi phân vân, hãy dùng dấu ngoặc.

Kiểm tra nhanh

1. 10 / 3 bằng bao nhiêu khi cả hai vế đều là số nguyên?

2. Các toán tử so sánh như == và < luôn trả về kiểu gì?

3. Cần điều gì để score += 5; biên dịch được?

Điểm: 0 / 3