<h2>Estruturas Condicionais: If e Match</h2>
<p>A tomada de decisão é fundamental em qualquer programa. Em Rust, a estrutura <code>if</code> funciona de forma semelhante a outras linguagens, mas com uma característica única: é uma expressão, não apenas uma declaração. Isso significa que você pode atribuir o resultado de um <code>if</code> a uma variável.</p>
<pre><code class="language-rust">fn main() {
let idade = 18;
// If como declaração
if idade >= 18 {
println!("Você é maior de idade");
} else if idade >= 13 {
println!("Você é adolescente");
} else {
println!("Você é criança");
}
// If como expressão
let categoria = if idade >= 18 { "adulto" } else { "menor" };
println!("Categoria: {}", categoria);
}</code></pre>
<p>Rust também oferece o <code>match</code>, que é mais poderoso e seguro que o <code>switch</code> tradicional. O <code>match</code> força você a cobrir todos os casos possíveis, prevenindo bugs sutis. Ele é ideal quando você quer trabalhar com enums ou múltiplos padrões.</p>
<pre><code class="language-rust">fn main() {
let numero = 3;
match numero {
1 => println!("Um"),
2 => println!("Dois"),
3 => println!("Três"),
_ => println!("Outro número"),
}
// Match com enums
enum Resultado {
Sucesso(String),
Erro(i32),
}
let resultado = Resultado::Sucesso("Operação concluída".to_string());
match resultado {
Resultado::Sucesso(msg) => println!("✓ {}", msg),
Resultado::Erro(codigo) => println!("✗ Código de erro: {}", codigo),
}
}</code></pre>
<h2>Loops: Estruturas de Repetição</h2>
<p>Rust oferece três formas de criar loops, cada uma com seu propósito específico. O loop <code>loop</code> é uma repetição infinita que você controla com <code>break</code>. Use-o quando precisa sair do loop dinamicamente, com a flexibilidade de retornar um valor.</p>
<pre><code class="language-rust">fn main() {
let mut contador = 0;
// Loop infinito com controle manual
loop {
contador += 1;
println!("Iteração: {}", contador);
if contador == 5 {
break; // Sai do loop
}
}
// Loop retornando um valor
let resultado = loop {
contador += 1;
if contador == 10 {
break contador * 2; // Retorna 20
}
};
println!("Resultado: {}", resultado);
}</code></pre>
<p>O <code>while</code> executa enquanto uma condição é verdadeira. É ideal para cenários onde você precisa verificar uma condição antes de cada iteração. Diferente do <code>loop</code>, você não consegue retornar um valor diretamente do <code>while</code>.</p>
<pre><code class="language-rust">fn main() {
let mut numero = 1;
while numero <= 5 {
println!("Número: {}", numero);
numero += 1;
}
// Exemplo prático: entrada do usuário
let mut tentativas = 0;
while tentativas < 3 {
println!("Tentativa {}", tentativas + 1);
tentativas += 1;
}
}</code></pre>
<h2>For: Iteração Segura e Idiomática</h2>
<p>O <code>for</code> em Rust é muito diferente de linguagens como C. Ele itera sobre coleções (ranges, vetores, etc.) de forma segura, eliminando erros de índice. É a forma mais comum e recomendada de repetição quando você conhece antecipadamente sobre o que quer iterar.</p>
<pre><code class="language-rust">fn main() {
// For com range
for i in 1..=5 {
println!("Número: {}", i);
}
// For com vetor
let numeros = vec![10, 20, 30, 40];
for num in numeros {
println!("Valor: {}", num);
}
// For com índice (não idiomático, evite)
let letras = vec!['a', 'b', 'c'];
for (indice, letra) in letras.iter().enumerate() {
println!("{}: {}", indice, letra);
}
// For com referência (quando não quer consumir)
let valores = vec![5, 10, 15];
for &valor in &valores {
println!("Valor: {}", valor);
}
}</code></pre>
<h3>Diferenças Entre Range e Iteradores</h3>
<p>A notação <code>1..5</code> cria um range exclusivo (1 a 4), enquanto <code>1..=5</code> é inclusivo (1 a 5). Para vetores, use <code>iter()</code> para iteração por referência (mantém a posse do vetor) ou a iteração direta para consumir. A escolha entre <code>loop</code>, <code>while</code> e <code>for</code> deve se basear na clareza do código: use <code>for</code> quando possível, é mais seguro e idiomático em Rust.</p>
<pre><code class="language-rust">fn main() {
// Consumindo vs referência
let dados = vec![1, 2, 3];
for x in &dados {
println!("{}", x);
}
println!("dados ainda está disponível: {:?}", dados);
// Break e continue funcionam em todos os loops
for i in 1..10 {
if i == 3 {
continue; // Pula para próxima iteração
}
if i == 8 {
break; // Sai do loop
}
println!("{}", i);
}
}</code></pre>
<h2>Conclusão</h2>
<p>Dominando estruturas de controle em Rust, você domina a base da lógica programada. Três aprendizados principais: <strong>(1) use <code>if</code> como expressão para código mais conciso, e <code>match</code> para segurança em padrões complexos;</strong> <strong>(2) escolha <code>loop</code> para controle fino, <code>while</code> para condições dinâmicas e <code>for</code> para iterações sobre coleções;</strong> <strong>(3) lembre que em Rust, <code>for</code> é a escolha idiomática — segura contra erros de índice e mais legível.</strong> Pratique cada estrutura em pequenos programas para internalizar quando usar cada uma.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://doc.rust-lang.org/book/ch03-05-control-flow.html" target="_blank" rel="noopener noreferrer">The Rust Programming Language - Control Flow</a></li>
<li><a href="https://doc.rust-lang.org/rust-by-example/flow_control.html" target="_blank" rel="noopener noreferrer">Rust by Example - Flow of Control</a></li>
<li><a href="https://doc.rust-lang.org/std/" target="_blank" rel="noopener noreferrer">Official Rust Standard Library Documentation</a></li>
<li><a href="https://rust-lang.github.io/api-guidelines/" target="_blank" rel="noopener noreferrer">Rust Design Patterns - Idioms</a></li>
<li><a href="https://doc.rust-lang.org/book/" target="_blank" rel="noopener noreferrer">Steve Klabnik & Carol Nichols - The Rust Programming Language (Oficial Book)</a></li>
</ul>