将闭包传递给特征方法:预期类型参数,找到闭包

2024-01-03

我对如何让它发挥作用有点困惑,我已经把它从真实的东西中删除了。我写了一个特质:

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

其中 'child' 参数add_child受到 和 的限制PropertyTags只是一个枚举。我已经包含了以下类型的模拟实现child演示我的用法:

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;
    }
}

然后这些将被用作:

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);
}

我收到错误:

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()

我设置了一个最小的游乐场示例,它重现了此处的问题:


问题是add_child声称接受任何Renderable<C>, where C can be any实现的类型Fn(&PropertyTags),但随后该函数尝试为其提供一个特定的闭包类型,该类型可能与C.

为了使其发挥作用,add_child的签名应该如下所示:

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

where AddChildCallback是具体类型的名称(实现Fn(&PropertyTags)).

这里的困难在于,一方面,闭包类型没有可以在 Rust 代码中使用的名称,另一方面,实现Fn手动编译器不稳定,因此需要夜间编译器。

我还要注意的是,通过将回调类型设置为类型参数,Renderable设置第一个回调后,无法分配不同类型的回调,因为第一个回调将确定该回调的具体类型Renderable。这可能适合您的使用,我只是想确保您意识到这一点。

如果您想要一个适用于稳定编译器(从 Rust 1.14.0 开始)的解决方案,那么您必须对回调进行装箱。add_child的签名将如下所示:

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

是一个更新的游乐场链接,其中包含示例实现Fn。请注意,参数为call, call_mut and call_once按照特征定义的要求,作为元组传递。为了完整性,代码复制如下:

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 {
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将闭包传递给特征方法:预期类型参数,找到闭包 的相关文章

随机推荐