我应该如何从父函数返回匿名函数来生成闭包?

Posted

技术标签:

【中文标题】我应该如何从父函数返回匿名函数来生成闭包?【英文标题】:How should I return an anonymous function from a parent function to generate a Closure? 【发布时间】:2022-01-01 03:24:09 【问题描述】:

我用这段代码 sn-p 解释我的问题。由于 main() 它按我的预期工作。现在我想把它移到 main() 之外的一个函数中。我还没有找到应该如何返回的语法。该文档似乎显示了许多方法,但我找不到确切的方法。

fn main() 
    println!("Hello, Rust!");

    let mut _i = 0;
    let mut closure = || -> i32 
        _i = _i + 1;
        _i
    ;

    println!("closure returns: ", closure());
    println!("closure returns: ", closure());
    println!("closure returns: ", closure());

    // OK, returns 1, 2, 3, ...

    // now i want to encapsulate this in a function, something like:
    let fn_closure = get_counter();

    println!("closure returns: ", fn_closure()); 
    println!("closure returns: ", fn_closure()); 
    println!("closure returns: ", fn_closure()); 

    // expect: returns 1, 2, 3, ...


// try failed - how returns the closure?
fn get_counter() -> || -> i32  //? 
    let mut _i = 1;
    let mut f = || -> i32 
        _i = _i + 1;
        _i
    ;
    f

换句话说,我想重现这个用 C# 但用 Rust 编写的相同示例

Console.WriteLine("Hello, C#!");

var closure = GetCounter();

Console.WriteLine("closure returns: 0", closure());
Console.WriteLine("closure returns: 0", closure());
Console.WriteLine("closure returns: 0", closure());

// OK, output is 1 , 2 , 3, ...

static Func<int> GetCounter()

    int _i = 0;
    return () => ++_i;

附:也许这是一个非常简单的概念性问题,对不起。

【问题讨论】:

请注意,前导下划线通常用于您使用的标识符。所以let mut _i 应该是let mut i 【参考方案1】:

您可以使用返回类型impl FnMut() -&gt; i32。这可以看作是“a concrete type that implements this trait(FnMut)” 的简写。在其他团队中,我们可以使用实现特征的某种类型的impl Trait syntax in the return position to return a value。从文档中引用。

闭包和迭代器创建只有编译器知道或 指定时间很长的类型。 impl Trait 语法让你 简明扼要地指定一个函数返回某种实现的类型 Iterator trait 不需要写出很长的类型。

fn main() 
    println!("Hello, Rust!");

    let mut _i = 0;
    let mut closure = || -> i32 
        _i = _i + 1;
        _i
    ;

    println!("closure returns: ", closure());
    println!("closure returns: ", closure());
    println!("closure returns: ", closure());


    let mut fn_closure = get_counter();

    println!("closure returns: ", fn_closure()); 
    println!("closure returns: ", fn_closure()); 
    println!("closure returns: ", fn_closure()); 



fn get_counter() -> impl FnMut() -> i32   
    let mut _i = 1;
    let f = move || -> i32 
        _i = _i + 1;
        _i
    ;
    f

另见

When does a closure implement Fn, FnMut and FnOnce?

【讨论】:

这正是我想要的! @AlexandraDanithAnsley 请注意,当一个问题的回答令他们满意时,提问者应该是accept 最佳答案。这样做会将问题标记为对未来的访客已解决,并奖励提供答案的志愿者以象征性的声誉奖励。

以上是关于我应该如何从父函数返回匿名函数来生成闭包?的主要内容,如果未能解决你的问题,请参考以下文章

Go函数

闭包 装饰器 偏函数

通过取父级for循环的i来理解闭包,iife,匿名函数

scala闭包/匿名函数中的多个返回点

go 匿名函数和闭包

关于js的闭包和匿名函数