closures rust

closures - No se puede pasar el cierre como parámetro



rust (2)

Esta pregunta ya tiene una respuesta aquí:

Estoy aprendiendo Rust ahora, y parece que no puedo especificar un cierre como un parámetro de función. Esto es lo que tengo:

fn foo(a: i32, f: |i32| -> i32) -> i32 { f(a) } fn main() { let bar = foo(5, |x| { x + 1 }); println!("{}", bar); }

Obtuve el siguiente error:

foo.rs:1:19: 1:20 error: expected type, found `|` foo.rs:1 fn foo(a: i32, f: |i32| -> i32) -> i32 {

De acuerdo, entonces no me gustó la sintaxis de cierre. Esto es un poco molesto, porque ahora tengo que escribir esto:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 { f(a) } fn main() { let bar = foo(5, Box::new(|x| { x + 1 })); println!("{}", bar); }

Entonces, ¿qué está pasando? He leído en algunos lugares diferentes que el primer ejemplo es válido, así que ¿se eliminó esta sintaxis del "parámetro de tipo de cierre" o simplemente estoy haciendo algo mal?


Rust se ha desarrollado abiertamente desde el principio y el lenguaje ha evolucionado mucho desde entonces. El artículo de Desbordamiento de pila con el que estás enlazando tiene casi 1 año de antigüedad, que en el tiempo de oxidación anterior a 1.0 es tan largo como la vida ... (juego de palabras intencionado)

La respuesta más directa sería: tenga en cuenta que una gran cantidad de artículos, publicaciones en blogs, respuestas SO ... ya no son relevantes porque el idioma cambió. Si intenta una solución y no funciona, simplemente encuentre la sintaxis más nueva (¡como lo hizo!) Y continúe.

Para este caso específico, este RFC documenta el cambio de |...| -> ... |...| -> ... a Fn/FnMut/FnOnce(...) -> ...

Por cierto, hay un plan para un esfuerzo de la comunidad para encontrar artículos obsoletos y marcarlos explícitamente como obsoletos, para evitar este problema en particular. Sin embargo, no puedo encontrar el enlace.


Si alguien está interesado en esta pregunta hoy, aquí está la sintaxis con genéricos:

fn foo<F: Fn(i32) -> i32>(a: i32, f: F) -> i32 { f(a) } fn main() { let bar = foo(5, |x| { x + 1 }); println!("{}", bar); }

O bien, usando objetos de rasgo:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 { f(a) } fn main() { let bar = foo(5, Box::new(|x| { x + 1 })); println!("{}", bar); }

Deberías preferir lo primero.