Laços de Repetição for
for
e o limite
A construção for in
pode ser usada para iterar através dum Iterator
. Uma das maneiras mais fáceis de criar um iterador é usar a notação de limite a..b
. Isto produz valores a partir de a
(inclusivo) à b
(exclusivo) em passos de um.
Vamos escrever FizzBuzz usando for
ao invés de while
.
fn main() { // `n` receberá os valores: 1, 2, ..., 100 em cada iteração for n in 1..101 { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { println!("fizz"); } else if n % 5 == 0 { println!("buzz"); } else { println!("{}", n); } } }
Alternativamente, a..=b
pode ser usado para um limite que é inclusivo em ambos fins. O exemplo acima pode ser escrito como:
fn main() { // `n` receberá os valores: 1, 2, ..., 100 em cada iteração for n in 1..=100 { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { println!("fizz"); } else if n % 5 == 0 { println!("buzz"); } else { println!("{}", n); } } }
for
e os iteradores
A construção for in
é capaz de interagir com um Iterator
de muitas maneiras. Conforme discutido na seção sobre a característica Iterator
, por padrão o laço for
aplicará a função into_iter
à coleção. No entanto, isto não é o único significado de converter coleções em iteradores.
into_iter
, iter
e iter_mut
manipulam a conversão duma coleção num iterador de maneiras diferentes, fornecendo visões diferentes sobre os dados no interior.
iter
- Este pedi emprestado cada elemento da coleção durante cada iteração. Assim deixando a coleção intocada e disponível para reuso depois do laço.
fn main() { let names = vec!["Bob", "Frank", "Ferris"]; for name in names.iter() { match name { &"Ferris" => println!("There is a rustacean among us!"), // TODO ^ Tente eliminar o & e corresponder apenas "Ferris" _ => println!("Hello {}", name), } } println!("names: {:?}", names); }
into_iter
- Este consume a coleção para que em cada iteração o dado exato ser fornecido. Assim que a coleção tiver sido consumida não estará disponível para reuso como se tivesse sido 'movida' dentro do laço.
fn main() { let names = vec!["Bob", "Frank", "Ferris"]; for name in names.into_iter() { match name { "Ferris" => println!("There is a rustacean among us!"), _ => println!("Hello {}", name), } } println!("names: {:?}", names); // FIXME ^ Comente esta linha }
iter_mut
- Este pedi emprestado de maneira mutável cada elemento da coleção, permitindo a coleção ser modificada no lugar.
fn main() { let mut names = vec!["Bob", "Frank", "Ferris"]; for name in names.iter_mut() { *name = match name { &mut "Ferris" => "There is a rustacean among us!", _ => "Hello", } } println!("names: {:?}", names); }
Nos trechos acima nota o tipo do ramo match
, que é a diferença chave nos tipos de iteração. A diferença no tipo portanto com certeza implica que diferentes ações que são capazes de ser realizadas.