Laços e Intervalos em Rust

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Neste laboratório, aprendemos sobre o uso de loops for e ranges em Rust. Podemos usar o loop for juntamente com a notação de range a..b para iterar através de um intervalo de valores. Por exemplo, podemos escrever o programa FizzBuzz usando um loop for em vez de um loop while. Além disso, podemos usar a notação ..= para um intervalo inclusivo em ambas as extremidades. O loop for também pode interagir com iteradores de diferentes maneiras, como usar iter para emprestar cada elemento de uma coleção, into_iter para consumir a coleção ou iter_mut para emprestar mutávelmente cada elemento da coleção. Cada um desses métodos fornece uma visão diferente dos dados dentro da coleção, permitindo que diferentes ações sejam executadas.

Nota: Se o laboratório não especificar um nome de arquivo, você pode usar qualquer nome de arquivo que desejar. Por exemplo, você pode usar main.rs, compilar e executá-lo com rustc main.rs && ./main.

Loops for

for e range

A construção for in pode ser usada para iterar através de um Iterator. Uma das maneiras mais fáceis de criar um iterador é usar a notação de intervalo a..b. Isso gera valores de a (inclusivo) a b (exclusivo) em incrementos de um.

Vamos escrever FizzBuzz usando for em vez de while.

fn main() {
    // `n` assumirá 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 intervalo inclusivo em ambas as extremidades. O código acima pode ser reescrito como:

fn main() {
    // `n` assumirá 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 iteradores

A construção for in é capaz de interagir com um Iterator de várias maneiras. Como discutido na seção sobre o trait Iterator, por padrão, o loop for aplicará a função into_iter à coleção. No entanto, este não é o único meio de converter coleções em iteradores.

into_iter, iter e iter_mut lidam com a conversão de uma coleção em um iterador de maneiras diferentes, fornecendo diferentes visões dos dados dentro dela.

  • iter - Este método empresta cada elemento da coleção em cada iteração. Assim, deixando a coleção intacta e disponível para reutilização após o loop.
fn main() {
    let names = vec!["Bob", "Frank", "Ferris"];

    for name in names.iter() {
        match name {
            &"Ferris" => println!("Há um rustacean entre nós!"),
            // TODO ^ Tente remover o & e corresponder apenas a "Ferris"
            _ => println!("Olá {}", name),
        }
    }

    println!("names: {:?}", names);
}
  • into_iter - Este método consome a coleção para que, em cada iteração, os dados exatos sejam fornecidos. Uma vez que a coleção foi consumida, ela não está mais disponível para reutilização, pois foi 'movida' dentro do loop.
fn main() {
    let names = vec!["Bob", "Frank", "Ferris"];

    for name in names.into_iter() {
        match name {
            "Ferris" => println!("Há um rustacean entre nós!"),
            _ => println!("Olá {}", name),
        }
    }

    println!("names: {:?}", names);
    // FIXME ^ Comente esta linha
}
  • iter_mut - Este método empresta mutávelmente cada elemento da coleção, permitindo que a coleção seja modificada no local.
fn main() {
    let mut names = vec!["Bob", "Frank", "Ferris"];

    for name in names.iter_mut() {
        *name = match name {
            &mut "Ferris" => "Há um rustacean entre nós!",
            _ => "Olá",
        }
    }

    println!("names: {:?}", names);
}

Nos trechos acima, observe o tipo do ramo match, que é a principal diferença nos tipos de iteração. A diferença no tipo, é claro, implica ações diferentes que podem ser executadas.

Resumo

Parabéns! Você concluiu o laboratório de Loops for. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.