Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

263
Vistas
¿Por qué este cierre requiere inline o `dyn`? ¿Qué hace `dyn` aquí?

Estoy confundido acerca de lo que está pasando con las vidas a continuación:

 struct Foo{} impl Foo { fn foo(&self, _s: &str) {} } fn main() { let foo = &Foo{}; let closure = |s| foo.foo(s); // Part 1: error message about wrong lifetime in FnOnce take_closure(closure); // Part 2: no error when inlined take_closure(|s| foo.foo(s)); // Part 3: no error when `dyn`d and given explicit signature let closure: &dyn Fn(&str) -> _ = &|s| foo.foo(s); take_closure(closure); } fn take_closure(f: impl Fn(&str) -> ()) { let s = get_string(); f(&s) } fn get_string() -> String { "".to_string() }

patio de recreo

  1. ¿Por qué falla la Parte 1?
  2. ¿Por qué la Parte 2 no falla?
  3. ¿Por qué la Parte 3 no falla y qué sucede realmente en la Parte 3? ¿Rust hace una vtable? Las salidas LLVM difieren entre 2 y 3
  4. ¿Hay una mejor manera? Inlining es feo y dyn es feo y me hace preguntarme qué es lo que realmente hace.
over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

¿Por qué falla la Parte 1?

La inferencia de tipos de Rust no es excelente para decidir qué tipo debe tener un cierre, cuando el cierre se declara por separado de donde se usa. Cuando el cierre acepta referencias, el compilador a menudo asume que habrá algún tiempo de vida específico que estará involucrado, no “cualquier tiempo de vida que la persona que llama quiera proporcionar”, como realmente se requiere aquí.

De hecho, hay un Rust RFC activo para mejorar esto al agregar otra forma de especificar parámetros de vida útil en los cierres. (El RFC también contiene un ejemplo en el que hacer la suposición de vida útil opuesta no funcionaría).

¿Qué sucede realmente en la parte 3? ¿Rust hace una vtable?

Sí, hay una vtable involucrada cada vez que usa dyn . Eso no es especialmente relevante para la causa raíz aquí; es solo que el tiempo de vida elidido en dyn Fn(&str) se resolvió de la manera que necesitaba en lugar de la forma en que no lo hizo.

¿Hay una mejor manera? Inlining es feo y dyn es feo y me hace preguntarme qué es lo que realmente hace.

Colocar un cierre directamente en la expresión de llamada a la función que lo usa es un estilo muy común de Rust, y le recomiendo que se ciña a él siempre que sea posible, ya que también es la forma que funciona bien con la inferencia de tipos.

Como solución alternativa en el caso de que necesite usar un cierre más de una vez, puede pasar el cierre a través de una función que restrinja su tipo:

 fn string_acceptor<F: Fn(&str) -> ()>(f: F) -> F { f } ... let foo = &Foo{}; let closure = string_acceptor(|s| foo.foo(s));
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda