Médio Rust
Contador com FnMut
Enunciado
Implemente uma função executar_duas_vezes que recebe uma closure mutável e a chama duas vezes, retornando a soma dos resultados. Use uma closure que incrementa um contador interno e retorna o novo valor. Imprima a soma final.
Requisitos
- A função
executar_duas_vezesdeve aceitarF: FnMut() -> i32. - A closure deve capturar uma variável mutável e incrementá-la a cada chamada.
- O programa deve imprimir a soma dos dois retornos.
Código inicial
fn executar_duas_vezes<F: FnMut() -> i32>(mut f: F) -> i32 {
f() + f()
}
fn main() {
let mut contador = 0;
// Complete aqui: crie a closure e chame executar_duas_vezes
}
Saída esperada
3
Ver dica
A closure deve ser || { contador += 1; contador }. Lembre-se de declarar contador como mut.
Mostrar solução
fn executar_duas_vezes<F: FnMut() -> i32>(mut f: F) -> i32 {
f() + f()
}
fn main() {
let mut contador = 0;
// Closure que captura contador por empréstimo mutável
let mut incrementar = || {
contador += 1;
contador
};
let soma = executar_duas_vezes(&mut incrementar);
println!("{}", soma);
}
Passo a passo
- Definimos
executar_duas_vezesque recebemut f: FondeF: FnMut() -> i32. - Dentro de
main, criamoscontadormutável iniciado em 0. - Criamos a closure
incrementarque capturacontadorpor empréstimo mutável, incrementa e retorna o novo valor. - Chamamos
executar_duas_vezespassando&mut incrementar(a função precisa de uma referência mutável à closure). - A função chama a closure duas vezes: primeiro retorna 1, depois 2, e soma 3.
- Imprimimos a soma.
Por que funciona
A closure modifica contador, então captura por empréstimo mutável, implementando FnMut. A função executar_duas_vezes aceita FnMut e pode chamá-la múltiplas vezes. Passamos &mut incrementar porque a função precisa de uma referência mutável para chamar a closure que muta o ambiente.
Erros comuns
- Declarar
contadorsemmut: a closure não poderia modificar, gerando erro de compilação. - Passar
incrementarsem&mut: a função esperaF: FnMut, mas passar por valor moveria a closure; usar&mutpermite empréstimo mutável. - Esquecer de declarar
fcomomutna assinatura deexecutar_duas_vezes: sem isso, não é possível chamarf()que requer&mut self.
Outra forma de resolver
Poderia usar move para capturar contador por valor, mas aí o contador seria movido para dentro da closure e não poderia ser usado fora. A versão com empréstimo mutável é mais flexível.
Saída esperada
3