【问题标题】: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

标签: rust closures


【解决方案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
}

另见

【讨论】:

  • 这正是我想要的!
  • @AlexandraDanithAnsley 请注意,当一个问题的回答令他们满意时,提问者应该是accept 最佳答案。这样做会将问题标记为对未来的访客已解决,并奖励提供答案的志愿者以象征性的声誉奖励。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
相关资源
最近更新 更多