问题是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 {
}
}