Rust: Loops e iteração em Rust

Última atualização: 2026-08-26

Um loop em Rust não é apenas um simples “loop infinito” — ele “retorna” o valor do último cálculo.

Cada um dos três tipos de loops tem seu próprio caso de uso: loop loops infinitos (com valores de retorno), while loops condicionais e for iteração de conjuntos.


1. O que você vai aprender


2. A história de um explorador de labirintos

(1) Sofrimento: se perder em um labirinto

Alex está desenvolvendo um jogo de labirinto. O labirinto tem uma estrutura aninhada de três camadas:

TEXT 📖 Somente leitura
Outer layer (Dungeon) -> Middle layer (Room) -> Inner layer (Treasure Chest)

O jogador precisa ir cada vez mais fundo para encontrar a saída, mas está tendo dificuldade para escrever o código:

“Se pudéssemos identificar cada loop, poderíamos simplesmente pular para onde quiséssemos...”

(2) A solução do Rust para loops

RUST
fn main() {
    let mut found_exit = false;
    let maze = [
        ["empty", "empty", "key"],
        ["empty", "monster", "empty"],
        ["exit", "empty", "trap"],
    ];

    // Outer Label 'outer Naming Dungeon Cycles
    'outer: for (row, floor) in maze.iter().enumerate() {
        println!("Enter the dungeon, Floor #{}", row + 1);
        for (col, room) in floor.iter().enumerate() {
            match *room {
                "exit" => {
                    println!("  Find the Exit!Location: ({}, {})", row, col);
                    found_exit = true;
                    break 'outer;  // Exit two nested loops immediately
                }
                "key" => println!("  Get the keys (Location: {},{})", row, col),
                "monster" => println!("  There's a monster!Skip this room"),
                _ => println!("  Vacant Room {}", col),
            }
        }
    }

    println!("Have you found the exit?: {}", found_exit);
}

As etiquetas de loop do Rust ('outer) permitem break sair de loops em qualquer nível. Isso é mais seguro do que goto — não salta para um local arbitrário no código, mas apenas sai do loop.


3. Comparação dos três loops

100%
graph TB
    A[Rust Loop] --> B[loop: Infinite Loop]
    A --> C[while: Conditional Loops]
    A --> D[for: Set Iteration]
    B --> E[Until break up to and including]
    B --> F[Available break Return Value]
    C --> G[Check the condition before each loop]
    D --> H[Iterating Through a Set Automatically/Scope]
    D --> I[Most Commonly Used,Safest]
Características loop while for
Quando usar Condição de término indefinida Orientado por condição Iteração sobre um conjunto ou intervalo
Valor de retorno break value Pode retornar um valor Não pode retornar um valor Não pode retornar um valor
Infinite Loop Nativo while true Não é adequado
Desempenho Ótimo (o compilador sabe que haverá um loop) Ligeiramente pior (verifica a condição a cada vez) Ótimo (controlado diretamente pelo iterador)
Casos de uso Repetição/Polling Espera condicional Iteração por matrizes/vetores/intervalos

(2) Comparando break e continue

Palavra-chave Função Pode retornar um valor Usada com tags
break Sair do loop atual break value; (somente no loop) break 'label;
continue Pular o restante deste loop Não é possível continue 'label;

(3) Expressões de escopo

Notação Significado Inclui o valor final Exemplo
start..end Intervalo semiaberto Não 0..5 → 0, 1, 2, 3, 4
start..=end Intervalo fechado Sim 0..=5 → 0, 1, 2, 3, 4, 5
..end De 0 até o fim Não ..3 → 0, 1, 2
start.. Do início ao fim 3.. → 3, 4, 5, ...

4. Exemplos de loops

▶ Exemplo 1: Loops infinitos com loop e valores de retorno com break (Dificuldade ⭐)

RUST
// ============================================
// loop Loop:A simulation of the "Guess the Number" game"Let's try again"
// ============================================

fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;
        if counter == 5 {
            break counter * 2;  // break Can have a return value!
        }
    };

    println!("Loop ran 5 times, break returned: {}", result);

    // Real-World Scenarios:Keep trying until you succeed
    let mut attempts = 0;
    let success = loop {
        attempts += 1;
        if attempts >= 3 {
            break true;
        }
        // Simulate a failed operation,Keep trying
    };
    println!("Retry {} Success on the next attempt: {}", attempts, success);
}

Resultado:

TEXT 📖 Somente leitura
Loop ran 5 times, break returned: 10
Retry 3 Success on the next attempt: true

loop é a única estrutura de loop em Rust capaz de retornar um valor. Um valor de retorno pode vir diretamente após a palavra-chave break, sem a necessidade de uma variável adicional. Isso é muito útil no padrão “tentar até conseguir”.


▶ Exemplo 2: while Laço condicional (Dificuldade ⭐)

RUST
// ============================================
// while Loop:Countdown in Decreasing Order
// ============================================

fn main() {
    let mut countdown = 5;

    while countdown > 0 {
        println!("Countdown: {}...", countdown);
        countdown -= 1;
    }

    println!("Launch!");
}

Resultado:

TEXT 📖 Somente leitura
Countdown: 5...
Countdown: 4...
Countdown: 3...
Countdown: 2...
Countdown: 1...
Launch!

while Verifique a condição antes do início de cada iteração. Se a condição for false, pule todo o corpo do loop. Isso é adequado para cenários em que “o número de iterações é desconhecido, mas a condição de término é conhecida”.


▶ Exemplo 3: Iteração com for e intervalos (Dificuldade ⭐⭐)

RUST
// ============================================
// for Loop:Iteration Range,Arrays and Strings
// ============================================

fn main() {
    // 1. Range Iteration: 0..5 is 0 to 4 (Excludes 5)
    println!("-- Scope 0..5 --");
    for i in 0..5 {
        print!("{} ", i);
    }
    println!();

    // 2. Closing Range:0..=5 Includes 5
    println!("-- Scope 0..=5 --");
    for i in 0..=5 {
        print!("{} ", i);
    }
    println!();

    // 3. Iterate through an array
    let fruits = ["apple", "banana", "cherry"];
    println!("-- List of Fruits --");
    for fruit in &fruits {
        println!("{}", fruit);
    }

    // 4. Indexed Iteration(enumerate)
    println!("-- Indexed Iteration --");
    for (index, fruit) in fruits.iter().enumerate() {
        println!("Fruit #{}: {}", index, fruit);
    }
}

Resultado:

TEXT 📖 Somente leitura
-- Scope 0..5 --
0 1 2 3 4
-- Scope 0..=5 --
0 1 2 3 4 5
-- List of Fruits --
apple
banana
cherry
-- Indexed Iteration --
Fruit #0: apple
Fruit #1: banana
Fruit #2: cherry

for é a forma mais recomendada de fazer um loop em Rust. Ela evita o acesso fora dos limites e lida automaticamente com a iteração. 0..n é um intervalo semiaberto (excluindo n), 0..=n é um intervalo fechado (incluindo n). .enumerate() atribui um índice a cada elemento.


▶ Exemplo 4: Etiquetas de loop e loops aninhados (Dificuldade ⭐⭐⭐)

RUST
// ============================================
// Loop Label:break 'label Breaking Out of Multiple Levels of Nesting
// ============================================

fn main() {
    let matrix = [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
    ];

    let mut found = 0;

    // 'search Outer Loop for Tag Marking
    'search: for (i, row) in matrix.iter().enumerate() {
        for (j, &val) in row.iter().enumerate() {
            if val == 5 {
                println!("Find the Target 5 At the location ({}, {})", i, j);
                found = val;
                break 'search;  // Exit two nested loops immediately!
            }
        }
    }

    println!("Values found: {}", found);

    // continue It can also be used in conjunction with tags.
    'outer: for x in 0..3 {
        for y in 0..3 {
            if x == y {
                continue 'outer;  // Skip the remaining inner layers,Continue to the next outer layer
            }
            println!("x={}, y={}", x, y);
        }
    }
}

Resultado:

TEXT 📖 Somente leitura
Find the Target 5 At the location (1, 1)
Values found: 5
x=1, y=0
x=2, y=0
x=2, y=1

Sem um rótulo, break e continue afetam apenas o loop mais interno. Ao adicionar um rótulo ('name), é possível controlar loops em qualquer nível. Essa é uma maneira mais controlada de “sair” do que goto.


▶ Exemplo 5: Exercício abrangente — FizzBuzz e a tabuada (Dificuldade ⭐⭐)

RUST
// ============================================
// Comprehensive Cycle Practice:FizzBuzz + The 9×9 Multiplication Table
// ============================================

fn main() {
    println!("=== FizzBuzz (1-30) ===");
    for n in 1..=30 {
        match (n % 3, n % 5) {
            (0, 0) => print!("FizzBuzz "),
            (0, _) => print!("Fizz "),
            (_, 0) => print!("Buzz "),
            _ => print!("{} ", n),
        }
        if n % 10 == 0 { println!(); }
    }
    println!();

    println!("\n=== The 9×9 Multiplication Table ===");
    for i in 1..=9 {
        for j in 1..=i {
            print!("{}×{}={:<4}", j, i, i * j);
        }
        println!();
    }

    println!("\n=== while let Simulated Read ===");
    let mut queue = vec![10, 20, 30, 40, 0];
    while let Some(item) = queue.pop() {
        if item == 0 {
            println!("Encountered a termination signal,Stop Processing");
            break;
        }
        println!("Projects in Progress: {}", item);
    }

    println!("\n=== loop Retry Mode ===");
    let attempts = try_connect(3);
    println!("Connection Results: {}", attempts);
}

fn try_connect(max_retries: u32) -> bool {
    let mut attempt = 0;
    loop {
        attempt += 1;
        println!("Attempt #{} to connect...", attempt);
        if attempt >= max_retries {
            break true;
        }
    }
}

Resultado:

TEXT 📖 Somente leitura
=== FizzBuzz (1-30) ===
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 
11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz 
Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 

=== The 9×9 Multiplication Table ===
1×1=1   
1×2=2   2×2=4   
1×3=3   2×3=6   3×3=9   
1×4=4   2×4=8   3×4=12  4×4=16  
1×5=5   2×5=10  3×5=15  4×5=20  5×5=25  
1×6=6   2×6=12  3×6=18  4×6=24  5×6=30  6×6=36  
1×7=7   2×7=14  3×7=21  4×7=28  5×7=35  6×7=42  7×7=49  
1×8=8   2×8=16  3×8=24  4×8=32  5×8=40  6×8=48  7×8=56  8×8=64  
1×9=9   2×9=18  3×9=27  4×9=36  5×9=45  6×9=54  7×9=63  8×9=72  9×9=81  

=== while let Simulated Read ===
Projects in Progress: 40
Projects in Progress: 30
Projects in Progress: 20
Projects in Progress: 10
Encountered a termination signal,Stop Processing

=== loop Retry Mode ===
Attempt #1 to connect...
Attempt #2 to connect...
Attempt #3 to connect...
Connection Results: true

O FizzBuzz é implementado de forma mais elegante usando a correspondência de padrões de tupla match; a tabuada de multiplicação utiliza um padrão de dois níveis for + intervalo; while let é adequado para lidar com o padrão de loop “continuar enquanto um valor for recuperado”; loop + break é adequado para a lógica de repetição de tentativas.


❓ Perguntas Frequentes

P: Qual é a diferença entre loop e while true? R: loop é a opção preferida no Rust. loop indica ao compilador: “Vou repetir o ciclo indefinidamente”, permitindo que o compilador realize otimizações mais eficazes. Além disso, loop pode retornar um valor, enquanto while true não pode.

P: Qual é a diferença entre for i in 0..n e for i in 0..=n? R: .. denota um intervalo semiaberto (excluindo n), enquanto ..= denota um intervalo fechado (incluindo n). for i in 0..3 itera sobre 0, 1, 2; for i in 0..=3 itera sobre 0, 1, 2, 3.

P: Ao iterar sobre um array, qual é a diferença entre &fruits e fruits.iter()? R: &fruits chama implicitamente into_iter para obter os elementos, enquanto fruits.iter() é mais explícito e claro. Os resultados são praticamente idênticos. A abordagem com iterador é mais explícita e mais flexível (por exemplo, chamadas encadeadas como .enumerate(), .filter(), etc.).

P: Como se usa o valor de retorno de break? R: A instrução break dentro de uma loop pode retornar um valor, assim como uma função: let x = loop { break 42; };. Isso é comumente usado em situações em que é necessário “continuar tentando até que um resultado válido seja obtido”, reduzindo assim a necessidade de variáveis de estado adicionais.

P: O que devo fazer se houver muitos loops aninhados? R: Considere extrair o loop interno para uma função. No entanto, se uma estrutura aninhada for realmente necessária, rotular o loop externo é uma abordagem de “saída controlada” no estilo do Rust.


📖 Resumo


📝 Exercícios

  1. Dificuldade ⭐: Use for para percorrer 0..=10, exibindo apenas os números pares (usando if i % 2 == 0 para verificar).
  2. Dificuldade ⭐⭐: Simule o valor de retorno usando loop + break: Encontre o primeiro valor maior que 6 em vec![1, 3, 5, 7, 9, 11] e retorne-o; se nenhum for encontrado, retorne -1.
  3. Dificuldade ⭐⭐⭐: Use um loop for de duas camadas para imprimir uma tabuada de 9x9, com cada linha formatada como 1x1=1 1x2=2 …. Pense em como usar os rótulos do loop para controlar a lógica de quebra de linha.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%