ventas venta una telefono tecnicas proceso por frases ejemplos como cierres cierre cerrar rust closures

rust - venta - Pasar el método de cierre al rasgo: parámetro de tipo esperado, cierre encontrado



tecnicas de cierre de ventas pdf (1)

El problema es que add_child afirma que acepta cualquier Renderable<C> , donde C puede ser de cualquier tipo que implemente Fn(&PropertyTags) , pero luego la función intenta darle un tipo de cierre específico que podría no ser el mismo que C

Para que esto funcione, la firma de add_child debe verse así:

pub fn add_child<REND>(&mut self, child: &mut REND) where REND: Renderable<AddChildCallback>

donde AddChildCallback es el nombre de un tipo concreto (que implementa Fn(&PropertyTags) ).

La dificultad aquí es que, por un lado, los tipos de cierre no tienen un nombre que pueda usarse en su código Rust, y por otro lado, implementar Fn manualmente es inestable, por lo que requiere un compilador nocturno.

También notaré que al hacer que el callback sea un parámetro de tipo, no se puede asignar a un Renderable una devolución de llamada de un tipo diferente después de que se haya establecido una primera devolución de llamada, ya que la primera devolución de llamada determinará el tipo concreto para el Renderable . Esto podría estar bien para su uso, solo quería asegurarme de que lo sabía.

Si desea una solución que funcione en compiladores estables (a partir de Rust 1.14.0), tendrá que marcar la devolución de llamada. La firma de add_child se vería así:

pub fn add_child<REND>(&mut self, child: &mut REND) where REND: Renderable<Box<Fn(&PropertyTags)>>

Aquí hay un enlace actualizado de juegos con una implementación de ejemplo de Fn . Tenga en cuenta que los parámetros para call , call_mut y call_once se pasan como una tupla, como lo requiere la definición de rasgo. El código se reproduce a continuación para completarlo:

struct RenderableCallback { } impl<''a> Fn<(&''a PropertyTags,)> for RenderableCallback { extern "rust-call" fn call(&self, args: (&''a PropertyTags,)) -> Self::Output { } } impl<''a> FnMut<(&''a PropertyTags,)> for RenderableCallback { extern "rust-call" fn call_mut(&mut self, args: (&''a PropertyTags,)) -> Self::Output { } } impl<''a> FnOnce<(&''a PropertyTags,)> for RenderableCallback { type Output = (); extern "rust-call" fn call_once(self, args: (&''a PropertyTags,)) -> Self::Output { } }

Estoy un poco perplejo sobre cómo hacer que esto funcione, lo he reducido de la realidad. Escribí un rasgo:

pub trait Renderable<F: Fn(&PropertyTags)> { fn set_property_changed_callback(&mut self, callback: Option<F>); }

Para qué el parámetro ''secundario'' de add_child está restringido y PropertyTags es solo una enumeración. He incluido implementaciones simuladas del tipo de child para demostrar mi uso:

pub struct Child<F: Fn(&PropertyTags)> { property_changed_callback: Option<F>, } impl<F: Fn(&PropertyTags)> Renderable<F> for Child<F> { fn set_property_changed_callback(&mut self, callback: Option<F>) { self.property_changed_callback = callback; } }

Entonces estos se usarían como:

pub fn add_child<REND, C>(&mut self, child: &mut REND) where C: Fn(&PropertyTags), REND: Renderable<C> { let tc = Some(|property_tag: &PropertyTags|{ }); child.set_property_changed_callback(tc); }

Me aparece el error:

child.set_property_changed_callback(tc); | ^^ expected type parameter, found closure | = note: expected type `std::option::Option<C>` = note: found type `std::option::Option<[closure@src/rendering/mod.rs:74:31: 76:18]>` = help: here are some functions which might fulfill your needs: - .take() - .unwrap()

He configurado un ejemplo de patio de recreo mínimo que reproduce los problemas aquí: https://play.rust-lang.org/?gist=bcc8d67f25ac620fe062032d8737954b&version=stable&backtrace=0