Szukaj…
Składnia
loop { block } // nieskończona pętla
while condition { blok }
podczas gdy Let Pattern = expr { blok }
dla wzorca w wyraż { blok } // wyraż musi implementować IntoIterator
kontynuuj // przeskocz na koniec korpusu pętli, rozpoczynając w razie potrzeby nową iterację
break // zatrzymaj pętlę
' label : loop { block }
„ etykieta : while warunek { blok }
' label : while Let Pattern = expr { blok }
etykieta : dla wzorca w wyrażeniu { blok }
Kontynuuj ' etykieta // przeskocz na koniec etykiety oznaczonej jako treść pętli, rozpoczynając w razie potrzeby nową iterację
break ' label // zatrzymaj etykietę pętli
Podstawy
W Rust są 4 zapętlone konstrukcje. Wszystkie poniższe przykłady dają takie same wyniki.
Nieskończone pętle
let mut x = 0;
loop {
if x > 3 { break; }
println!("{}", x);
x += 1;
}
Podczas gdy pętle
let mut x = 0;
while x <= 3 {
println!("{}", x);
x += 1;
}
Zobacz także: Jaka jest różnica między loop while true ?
Dopasowane do wzoru While Loops
Czasami są one znane jako pętle while let dla zwięzłości.
let mut x = Some(0);
while let Some(v) = x {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
Jest to równoważne match w bloku loop :
let mut x = Some(0);
loop {
match x {
Some(v) => {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
_ => break,
}
}
Dla pętli
W przypadku Rust pętla for może być używana tylko z „iterowalnym” obiektem (tzn. Powinna implementować IntoIterator ).
for x in 0..4 {
println!("{}", x);
}
Jest to równoważne z następującym fragmentem obejmującym while let :
let mut iter = (0..4).into_iter();
while let Some(v) = iter.next() {
println!("{}", v);
}
Uwaga: 0..4 zwraca obiekt Range który już implementuje cechę Iterator . Dlatego into_iter() nie jest konieczne, ale utrzymuje się tylko w celu zilustrowania tego, co for nie. Dla dogłębnie, zobacz oficjalne dokumenty dotyczące for pętli i IntoIterator .
Zobacz także: Iteratory
Więcej informacji na temat pętli
Jak wspomniano w IntoIterator , możemy użyć wszystkiego, co implementuje IntoIterator z pętlą for :
let vector = vec!["foo", "bar", "baz"]; // vectors implement IntoIterator
for val in vector {
println!("{}", val);
}
Oczekiwany wynik:
foo
bar
baz
Zauważ, że iteracja po vector w ten sposób zużywa go (po pętli for vector nie może być ponownie użyty). To dlatego IntoIterator::into_iter porusza self .
IntoIterator jest także implementowany przez &Vec<T> i &mut Vec<T> (uzyskując wartości odpowiednio z typami &T i &mut T ), dzięki czemu można zapobiec przesunięciu vector , po prostu przekazując go przez odniesienie:
let vector = vec!["foo", "bar", "baz"];
for val in &vector {
println!("{}", val);
}
println!("{:?}", vector);
Zauważ, że val jest typu &&str , ponieważ vector jest typu Vec<&str> .
Kontrola pętli
Wszystkie konstrukty przelotowe umożliwić korzystanie z break i continue oświadczenia. Wpływają na bezpośrednio otaczającą (wewnętrzną) pętlę.
Podstawowa kontrola pętli
break kończy pętlę:
for x in 0..5 {
if x > 2 { break; }
println!("{}", x);
}
Wynik 0
1
2
continue kończy bieżącą iterację
for x in 0..5 {
if x < 2 { continue; }
println!("{}", x);
}
Wynik 2
3
4
Zaawansowana kontrola pętli
Załóżmy teraz, że mamy zagnieżdżone pętle i chcemy break się do zewnętrznej pętli. Następnie możemy użyć etykiet pętli, aby określić, do której pętli ma zastosowanie break lub continue . W poniższym przykładzie 'outer jest etykietą nadaną zewnętrznej pętli.
'outer: for i in 0..4 {
for j in i..i+2 {
println!("{} {}", i, j);
if i > 1 {
continue 'outer;
}
}
println!("--");
}
Wynik 0 0
0 1
--
1 1
1 2
--
2 2
3 3
Dla i > 1 pętla wewnętrzna została iterowana tylko raz i -- nie została wydrukowana.
Uwaga: Nie należy mylić etykiety pętli ze zmienną dożywotnią. Zmienne dotyczące istnienia występują tylko obok & lub jako parametr ogólny w <> .