【问题标题】:How do I pass a capture a string in a closure without causing a compiler error?如何在闭包中传递捕获字符串而不导致编译器错误?
【发布时间】:2021-01-06 01:49:58
【问题描述】:

编译器对以下代码发出错误,我不知道如何修复它。请注意,它适用于非闭包(直接调用)情况,只是当我尝试在闭包中捕获值 s 时它会失败。解决此问题的正确方法是什么?

fn count_letter(data : String, c : char) -> i32 {
    data.chars().filter(|x| *x == c).count() as i32
}

fn main()
{
    // Pretend this has to be a String, even though in this toy example it could be a str
    let s = "there once was a man from nantucket".to_string();

    // Works
    println!("{:?}", count_letter(s, 'n'));

    // error[E0507]: cannot move out of `s`, a captured variable in an `FnMut` closure
    let result : Vec<(char, i32)> = ('a'..='z').map(|x| (x, count_letter(s.clone, x))).collect();
    println!("{:?}", result);
}

错误是:error[E0507]: cannot move out of sFnMut闭包中的捕获变量

【问题讨论】:

  • 第一个println! 中的count_letter 拥有字符串s 的所有权。这就是为什么在此之后您不能使用它的原因。 (不过,您错过了 s.clone 的括号)。如果您在第一次使用s 时添加另一个.clone,那么您的代码就可以了;)playground
  • 除非你真的需要 count_letter 来获取字符串数据的所有权(因此需要不断地克隆字符串),否则最好传递对字符串的引用:@987654322 @

标签: rust closures


【解决方案1】:

我猜你想要这种行为:

fn count_letter(data : &str, c : char) -> i32 {
    data.chars().filter(|x| *x == c).count() as i32
}

fn main()
{
    // Pretend this has to be a String, even though in this toy example it could be a str
    let s = "there once was a man from nantucket".to_string();

    // Works
    println!("{:?}", count_letter(&s, 'n'));
     
    // Also works
    let result : Vec<(char, i32)> = ('a'..='z').map(|x| (x, count_letter(&s, x))).collect();
    println!("{:?}", result);
}

【讨论】:

    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多