你能返回闭包或创建行为类似于闭包的可调用对象吗?[复制]

Can you return closures or create callable objects that behave like cloosures? [duplicate]

提问人:Makogan 提问时间:9/26/2023 更新时间:9/26/2023 访问量:28

问:

我一直遇到一个问题。例如,假设我有以下内容:

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

在这两种情况下,目标都是构造一个闭包,该闭包使用它从更广泛的范围继承的上下文来做一些事情。它们的存在是为了方便,调用者可以简单地自己定义它们,只是乏味和冗长。

你可以用宏替换它们,这样就可以了,但我倾向于尽可能避免使用宏。

如果结构是可调用的,则可以将功能定义为结构的方法并传递该方法,从而允许您返回一个闭包,例如不是闭包的对象。

一般来说,我只是不知道如何制作这些帮助程序,这些帮助程序试图最大限度地减少定义在我的代码中构造的闭包定义常见模式的乏味。

泛型 Rust 迭代器 闭包

评论


答:

2赞 drewtato 9/26/2023 #1

可以使用语法返回闭包。impl Trait

pub fn return_closure<T>(t: T) -> impl FnOnce(usize) -> T {
    move |i: usize| t
}

您可能需要返回 FnOnceFnMutFn,具体取决于闭包。

您的另一个示例可能如下所示:

pub fn iter_concentric_rings<'a>(&'a self, depth: usize)
    -> BFSIterator<impl Fn(usize, &Id) -> IterVerts + 'a>

你不能使结构可调用,但你可以创建另一个特征,并为闭包和某些结构实现它。