<h2>Funções em Rust: Sintaxe, Parâmetros e Retornos</h2>
<p>Funções são a base da organização de código em Rust. Diferente de muitas linguagens, Rust distingue claramente entre instruções (que não retornam valor) e expressões (que retornam). Uma função é declarada com a palavra-chave <code>fn</code>, seguida de um nome, parâmetros entre parênteses e, opcionalmente, um tipo de retorno precedido por <code>-></code>.</p>
<pre><code class="language-rust">fn add(a: i32, b: i32) -> i32 {
a + b
}
fn greet(name: &str) {
println!("Olá, {}!", name);
}
fn main() {
let result = add(5, 3);
println!("Resultado: {}", result);
greet("Maria");
}</code></pre>
<p>Note que em Rust, a última linha sem <code>;</code> é uma expressão que retorna seu valor. Se adicionar <code>;</code>, torna-se uma instrução que retorna <code>()</code> (unit type). Os parâmetros <strong>exigem anotação de tipo</strong> — isso é obrigatório e não há tipo padrão inferido. Funções podem retornar múltiplos valores usando tuplas, e o compilador força a tratativa correta de tipos, eliminando bugs em tempo de compilação.</p>
<h3>Closures e Funções Anônimas</h3>
<p>Closures são funções sem nome que capturam variáveis do escopo envolvente. São poderosas para programação funcional e callbacks. A sintaxe é <code>|parametros| { corpo }</code>, onde os tipos podem ser inferidos ou explícitos.</p>
<pre><code class="language-rust">fn main() {
let num = 5;
let add_num = |x| x + num; // Captura 'num' por referência
println!("{}", add_num(3)); // Imprime 8
let multiply = |a: i32, b: i32| -> i32 { a * b };
println!("{}", multiply(4, 2)); // Imprime 8
let values = vec![1, 2, 3, 4];
let doubled: Vec<i32> = values.iter().map(|x| x * 2).collect();
println!("{:?}", doubled); // [2, 4, 6, 8]
}</code></pre>
<p>Closures implementam os traits <code>Fn</code>, <code>FnMut</code> ou <code>FnOnce</code>, dependendo de como capturam variáveis. <code>Fn</code> captura por referência imutável, <code>FnMut</code> por referência mutável, e <code>FnOnce</code> consome a variável. O compilador infere automaticamente qual trait usar.</p>
<h2>Expressões: O Coração de Rust</h2>
<p>Em Rust, quase tudo é uma expressão. Blocos <code>{}</code>, loops, condicionais — todos retornam valores. Isso diferencia Rust de linguagens como C ou Java, onde essas estruturas são apenas instruções. Uma expressão não termina com ponto-e-vírgula; se terminar, vira uma instrução.</p>
<pre><code class="language-rust">fn main() {
// Expressão if
let number = 5;
let result = if number > 0 {
"positivo"
} else {
"não positivo"
};
println!("{}", result); // "positivo"
// Expressão match
let value = 42;
let message = match value {
0 => "zero",
1..=10 => "pequeno",
_ => "grande",
};
println!("{}", message); // "grande"
// Bloco como expressão
let x = {
let y = 5;
let z = 6;
y + z // Sem ; retorna o valor
};
println!("{}", x); // 11
}</code></pre>
<p>Esse design força o programador a pensar em fluxo de dados de forma mais explícita. A ausência de um <code>;</code> é sintaticamente significativa e intencional, evitando retornos acidentais de <code>()</code>.</p>
<h2>O Sistema de Tipos: Estático, Forte e Inteligente</h2>
<p>Rust possui um sistema de tipos estático e forte, onde cada valor tem um tipo conhecido em tempo de compilação. O sistema é tão rigoroso que evita classes inteiras de bugs. Além dos tipos primitivos (<code>i32</code>, <code>f64</code>, <code>bool</code>, <code>&str</code>), Rust oferece tipos compostos, genéricos e traits para abstraçãoe reutilização.</p>
<h3>Tipos Genéricos e Traits</h3>
<p>Genéricos permitem escrever código reutilizável sem sacrificar segurança de tipo. Traits definem comportamentos compartilhados entre tipos diferentes, funcionando como interfaces.</p>
<pre><code class="language-rust">// Função genérica
fn print_it<T: std::fmt::Display>(val: T) {
println!("Valor: {}", val);
}
// Trait customizado
trait Animal {
fn fazer_som(&self) -> &str;
}
struct Cachorro;
struct Gato;
impl Animal for Cachorro {
fn fazer_som(&self) -> &str {
"Au au!"
}
}
impl Animal for Gato {
fn fazer_som(&self) -> &str {
"Miau!"
}
}
fn main() {
print_it(42);
print_it("Olá");
let dog = Cachorro;
let cat = Gato;
println!("{}", dog.fazer_som()); // Au au!
println!("{}", cat.fazer_som()); // Miau!
}</code></pre>
<p>O bound <code>T: std::fmt::Display</code> garante que <code>T</code> implementa o trait <code>Display</code>. Isso permite que o compilador verifique segurança sem runtime overhead. Traits também viabilizam polimorfismo sem herança, seguindo composição sobre herança.</p>
<h3>Option e Result: Tratamento de Erros Seguro</h3>
<p>Rust não possui <code>null</code>; ao invés, usa <code>Option<T></code> para valores opcionais e <code>Result<T, E></code> para operações que podem falhar. Isso força o tratamento explícito de casos de erro.</p>
<pre><code class="language-rust">fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
Err("Divisão por zero!".to_string())
} else {
Ok(a / b)
}
}
fn main() {
match divide(10, 2) {
Ok(resultado) => println!("Resultado: {}", resultado),
Err(erro) => println!("Erro: {}", erro),
}
// Sintaxe '?' para propagação de erro
let result = divide(20, 5).unwrap_or(0);
println!("{}", result); // 4
}</code></pre>
<p>O operador <code>?</code> propaga erros automaticamente, reduzindo boilerplate. <code>unwrap()</code> extrai o valor ou panics se for erro; use apenas quando tiver certeza. Essa abordagem torna tratamento de erro explícito e impossível de ignorar.</p>
<h2>Conclusão</h2>
<p>Dominando funções, expressões e o sistema de tipos de Rust, você terá acesso à filosofia central da linguagem: <strong>segurança em tempo de compilação sem sacrificar performance</strong>. Primeira lição: funções e closures são ferramentas poderosas para composição de código. Segunda: expressões, não instruções, levam a um código mais funcional e previsível. Terceira: o sistema de tipos não é um obstáculo — é seu aliado contra bugs, forçando você a pensar claramente sobre possibilidades de erro e fluxo de dados.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://doc.rust-lang.org/book/ch03-03-how-functions-work.html" target="_blank" rel="noopener noreferrer">The Rust Book - Functions</a></li>
<li><a href="https://doc.rust-lang.org/rust-by-example/fn/closures.html" target="_blank" rel="noopener noreferrer">Rust by Example - Closures</a></li>
<li><a href="https://doc.rust-lang.org/book/ch10-02-traits.html" target="_blank" rel="noopener noreferrer">Rust Book - Traits</a></li>
<li><a href="https://doc.rust-lang.org/book/ch09-00-error-handling.html" target="_blank" rel="noopener noreferrer">Error Handling in Rust</a></li>
<li><a href="https://docs.rs/" target="_blank" rel="noopener noreferrer">Official Rust Documentation</a></li>
</ul>