我一直遇到一个问题。举例来说,我有以下内容:
fn make_iterator<'a, T>(t: &'a T) -> ///???
where T: SomeTrait
{
/* some complex logic*/
return |i:usize| {
let res = t.method(i);
t.other_method(res)
};
}
我正在尝试的一个实际例子:
pub fn iter_concentric_rings<'a>(&'a self, depth: usize)
where
V: Clone + Debug,
E: Clone + Debug,
F: Clone + Debug,
{
BFSIterator::new(self.id(), |depth, &id| {
let v = unsafe { (*self.mesh).vert_handle(id) };
v.iter_verts().map(|h| h.id())
})
}
在这两种情况下,目标都是构建一个闭包,该闭包利用它从更广泛的范围继承的上下文执行某些操作。它们的存在是为了方便,调用者可以简单地自己定义它们,这只是乏味和冗长。
您可以用宏替换它们,这会起作用,但我倾向于尽可能避免使用宏。
如果结构是可调用的,您可以将功能定义为结构的方法并传递它,从而允许您返回一个类似闭包的对象,而不是闭包。
总的来说,我只是不知道如何制作这些帮助器来尽量减少定义在我的代码中构建的闭包定义的常见模式的乏味。
您可以使用
impl Trait
语法返回闭包。
pub fn return_closure<T>(t: T) -> impl FnOnce(usize) -> T {
move |i: usize| t
}
FnOnce
、FnMut
或 Fn
,具体取决于关闭情况。
您的其他示例可能如下所示:
pub fn iter_concentric_rings<'a>(&'a self, depth: usize)
-> BFSIterator<impl Fn(usize, &Id) -> IterVerts + 'a>
您无法使结构可调用,但您可以创建另一个特征并为闭包和某些结构实现它。