Break và continue trong Rust
break và continue cho phép bạn ngắt vòng lặp sớm thay vì lúc nào cũng phải chạy đến cuối. Chúng hoạt động giống nhau trong cả ba loại vòng lặp: loop, while và for.
break — thoát hẳn khỏi vòng lặp
Phần tiêu đề “break — thoát hẳn khỏi vòng lặp”break dừng vòng lặp ngay lập tức, và chương trình nhảy tới dòng code nằm ngay sau vòng lặp:
fn main() { for i in 1..=10 { if i == 5 { break; } println!("{i}"); }}Kết quả:
1234Dù range đi tới 10, vòng lặp dừng ngay khi i chạm 5.
continue — bỏ qua, sang vòng kế tiếp
Phần tiêu đề “continue — bỏ qua, sang vòng kế tiếp”continue bỏ qua phần còn lại của lượt hiện tại và nhảy thẳng sang lượt tiếp theo, chứ không dừng hẳn vòng lặp:
fn main() { for i in 1..=10 { if i % 2 == 0 { continue; // bỏ qua số chẵn } println!("{i}"); }}Kết quả:
13579Mọi số chẵn đều bị bỏ qua — continue được kích hoạt, và vòng lặp chuyển thẳng sang giá trị tiếp theo của i mà không chạy println!.
Vòng lặp có nhãn
Phần tiêu đề “Vòng lặp có nhãn”Khi bạn lồng một vòng lặp vào trong vòng lặp khác, break/continue thông thường chỉ tác động lên vòng lặp trong cùng. Nếu bạn cần thoát khỏi vòng lặp ngoài từ bên trong vòng lặp lồng, hãy đặt cho vòng lặp ngoài một nhãn (label, viết dạng 'name:):
fn main() { 'outer: for x in 1..=3 { for y in 1..=3 { if x * y > 4 { break 'outer; } println!("{x} x {y} = {}", x * y); } }}Kết quả:
1 x 1 = 11 x 2 = 21 x 3 = 32 x 1 = 22 x 2 = 4Nếu không có nhãn, break chỉ dừng vòng lặp y bên trong, còn x vẫn tiếp tục. break 'outer; dừng cả hai cùng lúc. continue 'outer; cũng hoạt động tương tự, nếu bạn muốn nhảy sang lượt tiếp theo của vòng lặp ngoài thay vì dừng hẳn.
Cái bẫy continue trong vòng lặp while
Phần tiêu đề “Cái bẫy continue trong vòng lặp while”Trong vòng lặp for, giá trị tiếp theo tự động đến từ range, nên continue luôn an toàn. Vòng lặp while thì khác: bạn tự cập nhật bộ đếm, thường là ở cuối thân vòng lặp. Nếu continue nhảy qua lệnh cập nhật đó, bộ đếm không bao giờ thay đổi và vòng lặp chạy mãi mãi.
Phiên bản này cố bỏ qua số 3, nhưng nó bị treo. Đừng chạy nó:
fn main() { let mut i = 0; while i < 5 { if i == 3 { continue; // ❌ nhảy lên lại mà không đổi i } println!("{i}"); i += 1; }}Khi i bằng 3, continue quay lại điều kiện. i vẫn là 3, nên continue lại được kích hoạt, rồi lại nữa, mãi mãi. Cách sửa là cập nhật bộ đếm trước mọi thứ có thể gọi continue:
fn main() { let mut i = 0; while i < 5 { i += 1; // cập nhật trước, để continue không thể bỏ qua nó if i == 3 { continue; } println!("{i}"); }}Kết quả:
1245Đưa i += 1 lên đầu làm các số dịch đi một: vòng lặp này in từ 1 đến 5 thay vì từ 0 đến 4, nên hãy chỉnh điểm bắt đầu hoặc điều kiện nếu bạn cần khoảng cũ. Tốt hơn nữa, nếu bạn chỉ đang đếm, hãy dùng vòng lặp for qua một range và vấn đề này không thể xảy ra.
Luyện tập
Phần tiêu đề “Luyện tập”1. Bỏ qua các bội số của 3
Phần tiêu đề “1. Bỏ qua các bội số của 3”In các số từ 1 đến 10, nhưng bỏ qua mọi bội số của 3. Gợi ý: một số là bội số của 3 khi n % 3 == 0. Dùng continue để bỏ qua nó.
Xem lời giải
fn main() { for n in 1..=10 { if n % 3 == 0 { continue; } println!("{n}"); }}Kết quả:
124578102. Tìm cặp số có tích bằng 24
Phần tiêu đề “2. Tìm cặp số có tích bằng 24”Dùng hai vòng lặp for lồng nhau, x và y, cả hai đều chạy qua 1..=9. Tìm cặp đầu tiên mà x * y == 24, in nó ra và dừng cả hai vòng lặp. Gợi ý: đặt nhãn cho vòng lặp ngoài và dùng break 'outer;.
Xem lời giải
fn main() { 'outer: for x in 1..=9 { for y in 1..=9 { if x * y == 24 { println!("Tìm thấy: {x} x {y} = 24"); break 'outer; } } } println!("Đã tìm xong");}Kết quả:
Tìm thấy: 3 x 8 = 24Đã tìm xongThử đổi break 'outer; thành break; thông thường. Lúc này chỉ vòng lặp trong dừng lại, nên việc tìm kiếm vẫn tiếp tục và còn in ra 4 x 6, 6 x 4 và 8 x 3.
Tóm tắt
Phần tiêu đề “Tóm tắt”breakthoát khỏi vòng lặp ngay lập tức.continuebỏ qua phần còn lại của lượt hiện tại và chuyển sang lượt tiếp theo.- Một nhãn (
'outer:) cho phépbreak/continuenhắm tới vòng lặp ngoài từ bên trong vòng lặp lồng. - Trong vòng lặp
while, hãy cập nhật bộ đếm trước mọicontinue, nếu không vòng lặp có thể kẹt mãi mãi.
Kiểm tra nhanh
Phần tiêu đề “Kiểm tra nhanh”Kiểm tra nhanh
1. continue làm gì bên trong một vòng lặp?
2. Viết nhãn cho vòng lặp thế nào để break có thể nhắm tới nó từ một vòng lặp lồng?
3. Một vòng lặp while có continue không bao giờ kết thúc. Nguyên nhân khả dĩ nhất là gì?
Điểm: 0 / 3
Đọc thêm
Phần tiêu đề “Đọc thêm”- Loop Labels to Disambiguate Between Multiple Loops — The Rust Book (tiếng Anh): phần giới thiệu chính thức về nhãn, với ví dụ đếm ngược lồng nhau.
- Nesting and labels — Rust by Example (tiếng Anh): một ví dụ ngắn chạy được về
break 'outervàcontinue 'outer. - Loop Labels — The Rust Reference (tiếng Anh): các quy tắc chính xác về nơi có thể dùng nhãn.
- Biểu thức
break— The Rust Reference (tiếng Anh): cáchbreakhoạt động, kể cảbreakkèm giá trị. - Biểu thức
continue— The Rust Reference (tiếng Anh):continuelàm gì trong từng loại vòng lặp.