Introdução: Por que o loop for reverso em Rust é uma armadilha para iniciantes?
\n\nImagine a situação: você está migrando de Python para Rust. Tudo parece claro, mas quando precisa percorrer um array em ordem reversa — você escreve for i in 0..10 e descobre, surpreso, que Rust só vai para frente. Você tenta escrever for i in 10..0 — e obtém um loop vazio. Familiar? Se sim, você não está sozinho. A pergunta «How to make a reverse ordered for loop» no Stack Overflow acumulou milhares de visualizações, e não é surpresa.
Neste artigo, vamos analisar os principais erros que iniciantes cometem ao trabalhar com loops reversos em Rust e mostrar como evitá-los. Você aprenderá por que 10..0 não funciona, como usar o método .rev() e iteradores, e como não quebrar seu código ao trabalhar com vetores e slices. Vamos lá!
Erro nº1: Uso ingênuo do intervalo ao contrário
\n\nO erro mais comum é tentar escrever for i in 10..0 na esperança de que Rust entenda: "ah, o usuário quer ir na ordem reversa". Infelizmente, em Rust, o intervalo a..b sempre vai de a até b não inclusivo. Se a >= b, o intervalo é vazio.
// ❌ Erro: loop vazio\nfor i in 10..0 {\n println!("{}", i); // Nada será exibido\n}\n\nPor que isso acontece? Rust é uma linguagem rigorosa. Os intervalos não sabem se inverter automaticamente. Isso foi feito por desempenho e previsibilidade. Se 10..0 funcionasse como reverso, o compilador teria que verificar cada número com "será que o valor inicial é maior que o final?", o que tornaria os loops comuns mais lentos.
Como corrigir: use o método .rev()
\n\nA maneira correta é criar um intervalo crescente normal e, em seguida, chamar o método .rev(), que inverte o iterador:
// ✅ Correto: usando .rev()\nfor i in (0..10).rev() {\n println!("{}", i); // Exibirá: 9, 8, 7, ..., 0\n}\n\nObserve: usamos (0..10).rev(), e não 10..0. Os parênteses são obrigatórios, pois 0..10.rev() chamaria o método em 10, e não no intervalo. Este é outro erro comum.
Erro nº2: Esqueceu os parênteses ao redor do intervalo
\n\nO método .rev() é chamado em um iterador. O intervalo 0..10 é um iterador. Mas se você escrever 0..10.rev(), Rust interpreta isso como 0..(10.rev()), e o número inteiro 10 não tem o método rev(). O compilador emitirá um erro:
// ❌ Erro de compilação: número não tem método rev()\nfor i in 0..10.rev() {\n // error[E0599]: no method named `rev` found for integer `i32`\n}\n\nA solução é simples — use parênteses:
\n\n// ✅ Parênteses resolvem tudo\nfor i in (0..10).rev() {\n println!("{}", i);\n}\n\nErro nº3: Tentativa de inverter algo que não é um iterador
\n\nÀs vezes, iniciantes tentam aplicar .rev() diretamente a um vetor ou array:
let numbers = vec![1, 2, 3, 4, 5];\n\n// ❌ Erro: Vec não tem método rev()\nfor i in numbers.rev() {\n println!("{}", i);\n}\n\n.rev() é um método de iterador, não de coleção. Para inverter um vetor, primeiro você precisa obter um iterador com .iter() ou .into_iter(), e então chamar .rev():
let numbers = vec![1, 2, 3, 4, 5];\n\n// ✅ Correto: obtém o iterador, depois inverte\nfor i in numbers.iter().rev() {\n println!("{}", i); // Exibirá: 5, 4, 3, 2, 1\n}\n\nSe você precisar ter posse dos elementos (por exemplo, movê-los), use .into_iter().rev():
let numbers = vec![1, 2, 3, 4, 5];\n\nfor i in numbers.into_iter().rev() {\n println!("{}", i); // numbers agora