如何避免借用不使用克隆而移入闭包的值?

时间:2019-05-07 10:48:06

标签: rust

我试图了解Rust中的闭包。我写了这样的代码;

use std::ops::Add;

fn main() {
    let mut a = "a string".to_string();

    let mut cl = ||  {
        a.add(" another string");
    };

    cl();

    println!("{:?}", a);
}

我希望得到类似“一个字符串另一个字符串”的结果。在文档中它说尽量避免使用clone(),但是如果不使用a = a.clone().add(" another string"),我将无法编译此代码。

2 个答案:

答案 0 :(得分:2)

要回答您的原始问题:不能。这是因为您的字符串a已移到闭包中。但是,您无法将其恢复。请参阅Denys answer以获取解决方案。


解决此特定问题的方法是使用push_str而不是Add,因为push_str需要可变的引用,而不是移动的值。

fn main() {
    let mut a = "a string".to_string();

    let mut cl = || {
        a.push_str(" another string");
    };

    cl();

    println!("{:?}", a);
}

答案 1 :(得分:1)

一种解决方案是将值移至闭包,然后使其返回:

use std::ops::Add;

fn main() {
    let mut a = "a string".to_string();
    let cl = ||  {
        a.add(" another string")
    };
    a = cl();
    println!("{:?}", a);
}

但是捕获外部范围是相当有限的。例如,您不能以这种方式定义两个闭包。您可能需要一个更灵活的解决方案:

let a = "a string".to_string();
let c1 = |s: String|  {
    s.add(" another string")
};
let c2 = |s: String|  {
    s + " and another one"
};
let a = c1(a);
let a = c2(a);