Fluxo de Controle
Rust fornece if/else, três formas de loop (loop, while, for) e match exaustivo. Loops e branches podem produzir valores quando usados como expressões.
Receita
fn sum_evens(nums: &[i32]) -> i32 {
let mut total = 0;
for &n in nums {
if n % 2 == 0 {
total += n;
}
}
total
}
fn first_negative(nums: &[i32]) -> Option<i32> {
for &n in nums {
if n < 0 {
return Some(n);
}
}
None
}Quando usar: Qualquer ramificação ou iteração. Prefira for em vez de while com índice manual ao iterar coleções.
Exemplo de Trabalho
fn find_pair(target: i32, nums: &[i32]) -> Option<(usize, usize)> {
'outer: for i in 0..nums.len() {
for j in (i + 1)..nums.len() {
if nums[i] + nums[j] == target {
break 'outer (i, j);
}
}
}
}
fn retry<F: FnMut() -> bool>(mut f: F, max: u32) -> bool {
let mut attempts = 0;
loop {
if f() {
break true;
}
attempts += 1;
if attempts >= max {
break false;
}
}
}
fn main() {
let nums = [2, 7, 11, 15];
println!("{:?}", find_pair(9, &nums));
println!("{}", retry(|| false, 3));
}O que isso demonstra:
break 'outerrotulado sai de loops aninhados com um valor de tuplaloopcombreakcondicional implementa lógica de retentativa- Intervalo
0..nums.len()para acesso baseado em índice quando necessário Optionpara resultados ausentes em vez de valores sentinela
Mergulho Profundo
Formas de Loop
| Construção | Uso |
|---|---|
for x in iter | Iterar coleções, intervalos, adaptadores |
while cond | Loop até a condição ser falsa |
loop | Loop infinito até break (pode retornar valor) |
let squares: Vec<i32> = (0..5).map(|n| n * n).collect();Exaustividade do match
enum Color { Red, Green, Blue }
fn hex(c: Color) -> &'static str {
match c {
Color::Red => "#f00",
Color::Green => "#0f0",
Color::Blue => "#00f",
}
}Erros de compilador se uma variante estiver faltando. Use _ apenas quando você intencionalmente captura os casos restantes.
if let e while let
let Some(x) = opt else { return };
while let Some(line) = lines.next() {
println!("{line}");
}Correspondência parcial ergonômica sem match completo.
Armadilhas
- Condição
ifnão é bool -if 1 { }falha. Correção: Use comparações explícitas. - Intervalos off-by-one -
0..nexcluin. Correção: Use0..=npara fim inclusivo quando necessário. - Empréstimo em loops
for-for item in &vecempresta;for item in vecmove. Correção: Escolhaiter(),iter_mut(), ouinto_iter()deliberadamente. matchnão exaustivo - Adicionar variantes de enum quebra compilações. Correção: Trate como um recurso; atualize todos osmatch.- Discrepância de tipo de valor
break- Todos osbreakem umloopdevem retornar o mesmo tipo. Correção: Anote ou unifique tipos.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Adaptadores de iterador | Transformar/filtrar sem loop explícito | Efeitos colaterais precisam de clareza sequencial |
Cadeia if let | Verificações de padrão único | Muitas variantes precisam de match |
Macro matches! | Predicado booleano em padrão | Você precisa de valores vinculados |
| Recursão | Estrutura de árvore/grafo | Pilhas profundas correm risco de estouro |
FAQs
O loop `for` pode iterar sobre uma referência?
Sim. for x in &vec empresta elementos. for x in &mut vec empresta mutavelmente.
Como faço um loop com um índice?
for (i, v) in items.iter().enumerate() é idiomático. 0..len bruto funciona quando vizinhos são necessários.
O que `break` com um valor faz?
Em loop, break 42 faz a expressão do loop ser avaliada como 42.
O `while` pode retornar um valor?
Não. Apenas loop suporta break value. Use loop ou atribua dentro de while.
O que é `continue 'label`?
Pula para a próxima iteração do loop rotulado, como break rotulado.
Como funcionam os guardas em `match`?
match x { n if n > 0 => ..., _ => ... } adiciona uma condição booleana a um padrão.
O `switch` está disponível?
Não. Use match para correspondência de padrões exaustiva.
Posso fazer correspondência em intervalos?
Sim para inteiros e caracteres: 1..=5, 'a'..='z'.
O que é `else` de loop?
Não em Rust. Use flags break ou valores de retorno Option em vez disso.
Como iterar um `HashMap`?
for (k, v) in &map ou map.iter(). A ordem é arbitrária, a menos que você use BTreeMap.
Relacionados
- Funções e Expressões - blocos orientados a expressão
- Correspondência de Padrões com match - padrões
matchdetalhados - if let, let else & while let - correspondências parciais
- Adaptadores de Iterador - transformações sem loop
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.