0Pricing
Learn Rust Coding · Aula

Fn, FnMut, FnOnce

Características de closures

Fn, FnMut, FnOnce é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Learn Rust Coding, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Learn Rust Coding inclui 4 aulas no total.

As características dos fechamentos

Todo fechamento implementa automaticamente uma ou mais de três características, conforme a maneira como usa os valores capturados:

  • Fn — toma empréstimos imutáveis.
  • FnMut — toma empréstimos mutáveis.
  • FnOnce — assume a propriedade e pode ser chamado uma vez.
fn main() {
    let x = 5;
    let show = || println!("x is {}", x); // implements Fn
    show();
    show();
}

Fn: empréstimo imutável

Um fechamento que apenas lê os valores capturados implementa Fn. Ele pode ser chamado muitas vezes sem alterar nada.

fn main() {
    let greeting = String::from("Hi");
    let say = || println!("{}", greeting);
    say();
    say();
}

FnMut: empréstimo mutável

Um fechamento que altera um valor capturado implementa FnMut. A própria variável do fechamento precisa ser mut para que ele seja chamado.

fn main() {
    let mut count = 0;
    let mut increment = || {
        count += 1;
        println!("count {}", count);
    };
    increment();
    increment();
}

FnOnce: assume a propriedade

Um fechamento que move um valor capturado para fora do ambiente implementa FnOnce. Ele só pode ser chamado uma vez.

fn main() {
    let name = String::from("Ada");
    let consume = move || {
        let owned = name;
        println!("consumed {}", owned);
    };
    consume();
}

A hierarquia das características

As características formam uma hierarquia:

  • Todo Fn também é FnMut e FnOnce.
  • Todo FnMut também é FnOnce.

Assim, Fn é o mais flexível e FnOnce, o menos flexível.

fn main() {
    let value = 42;
    let read = || value; // Fn, so also FnMut and FnOnce
    println!("{}", read());
}

Passando Fn para funções

Uma função pode aceitar um fechamento especificando de qual característica precisa. Use genéricos com uma restrição de característica.

fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
    f(x)
}

fn main() {
    let double = |n| n * 2;
    println!("{}", apply(double, 9));
}

Aceitando FnMut

Se sua função precisar alterar um estado capturado, exija FnMut e marque o parâmetro como mut.

fn call_twice<F: FnMut()>(mut f: F) {
    f();
    f();
}

fn main() {
    let mut total = 0;
    call_twice(|| total += 1);
    // note: total is borrowed during the call
}

Aceitando FnOnce

Quando uma função chama o fechamento apenas uma vez e pode permitir que ele consuma valores, exija FnOnce.

fn run_once<F: FnOnce() -> String>(f: F) {
    let result = f();
    println!("{}", result);
}

fn main() {
    let s = String::from("done");
    run_once(move || s);
}

A palavra-chave move

A palavra-chave move força um fechamento a assumir a propriedade das variáveis capturadas em vez de tomar empréstimos delas.

Isso é essencial quando um fechamento precisa sobreviver ao escopo em que foi criado, como em threads.

fn main() {
    let data = vec![1, 2, 3];
    let printer = move || println!("{:?}", data);
    printer();
}

Como o Rust escolhe a característica

Você não escolhe a característica manualmente. O compilador decide com base no corpo do fechamento:

  • Apenas lê → Fn
  • Altera → FnMut
  • Move um valor capturado para fora → FnOnce
fn main() {
    let mut log = Vec::new();
    let mut record = |x: i32| log.push(x); // FnMut
    record(1);
    record(2);
    println!("{:?}", log);
}

Escolhendo a restrição correta

Como regra:

  • Aceite Fn quando precisar apenas chamar e ler.
  • Aceite FnMut quando o fechamento alterar o estado.
  • Aceite FnOnce quando uma única chamada for suficiente.

Escolha a restrição mais permissiva que seja adequada.

fn each<F: Fn(i32)>(items: &[i32], f: F) {
    for &i in items {
        f(i);
    }
}

fn main() {
    each(&[1, 2, 3], |n| println!("got {}", n));
}

Verificação rápida

Associe o comportamento de uma closure à sua trait.

Recapitulação

As três traits de closure:

  • Fn — faz empréstimo imutável e pode ser chamada repetidamente.
  • FnMut — faz empréstimo mutável e pode alterar o estado.
  • FnOnce — assume a propriedade e pode ser chamada uma vez.

O compilador infere a trait; move força a captura por propriedade.

fn main() {
    let base = 5;
    let adder = move |x: i32| x + base; // Fn, captures base by move
    println!("{}", adder(10));
}

Perguntas Frequentes

A aula “Fn, FnMut, FnOnce” é grátis?

Sim — o texto completo de “Fn, FnMut, FnOnce” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Learn Rust Coding, atualize para CoddyKit PRO. O curso de Learn Rust Coding inclui 4 aulas no total.

O que vou aprender em “Fn, FnMut, FnOnce”?

Características de closures Você pratica Learn Rust Coding com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Learn Rust Coding?

Nenhuma experiência prévia é necessária. Learn Rust Coding no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Fn, FnMut, FnOnce”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Learn Rust Coding?

Sim. Cada aula de Learn Rust Coding inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Definição de funções
  2. Expressões e instruções
  3. Closures
  4. Fn, FnMut, FnOnce
← Voltar para Learn Rust Coding