Ponteiros de Função vs. Closures
fn(i32) -> i32 é um ponteiro de função - sem ambiente capturado. Closures podem capturar estado e ter tipos únicos.
Receita
fn apply(f: fn(i32) -> i32, x: i32) -> i32 { f(x) }
fn inc(x: i32) -> i32 { x + 1 }
fn main() {
println!("{}", apply(inc, 5));
}Quando usar isso: Callbacks de FFI C, hooks simples sem captura e garantias Send + Sync de ponteiros de função.
Exemplo de Trabalho
fn call_with<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 { f(x) }
fn double(x: i32) -> i32 { x * 2 }
fn main() {
println!("{}", call_with(double, 3));
println!("{}", call_with(|x| x + 1, 3));
}O que isso demonstra:
- Funções nomeadas (
fn item) são coeridas para ponteiros de função quando esperado. Fngenérico aceita tanto itens de função quanto closures.- Closures com capturas não podem ser ponteiros de função (
fn).
Análise Detalhada
Itens de função (fn item) são coeridos para ponteiros de função. Closures sem capturas podem ser coeridas para ponteiros de função em alguns casos. FFI usa extern "C" fn.
Armadilhas
- Esperar ponteiro de função com closure de captura - Falha na coerção. Correção: Use
F: Fngenérico ouBox<dyn Fn>. - Ponteiro de função nulo - Nulo em FFI - não em Rust seguro sem
Option. - Método como ponteiro de função - Necessita de uma função simples (
fn) ou um closure que envolvaself. - Transmutar função - Comportamento indefinido (UB) se incorreto. Correção: Assinaturas corretas.
- Mito de performance - Closures sem captura frequentemente têm a mesma performance que funções (
fn).
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Closure | Precisa de captura | FFI precisa de extern fn |
extern "C" fn | Interoperabilidade com C | Apenas Rust puro |
Box<dyn Fn> | Callbacks heterogêneos | Ponteiro de função é suficiente |
FAQs
Tamanho de um ponteiro de função?
Uma palavra - o endereço.Tamanho de um closure?
O ambiente + ponteiro de função varia.Coerção de closure para fn?
Apenas closures não capturantes.Send Sync fn?
Ponteiros de função são sempre Send+Sync.fn variádica?
Apenas `extern C` é `unsafe`.Ponteiro de método?
Não é o mesmo que `fn` - use closure ou `fn(item)`.Callback do Tokio?
Frequentemente `ArcComparar?
Objetos de trait `Fn` para escolha em tempo de execução.no_std?
Ponteiros de função em `core`.Testar?
Passe a função `inc` para `apply`.Relacionados
Versões das Pilhas: 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+.