rust 将迭代器收集到向量中时克隆值

oknwwptz  于 2023-03-23  发布在  其他
关注(0)|答案(2)|浏览(164)

我正在写一个程序,它从stdin中获取几行输入。我将这一行读入一个字符串,然后将其拆分,并将单词收集到一个向量中。这个字符串(buffer)在后面的行中重用,这样我就不需要为每一行输入创建一个新的字符串。
然而,当我试图编译代码时,我发现我不能重用该字符串,因为它仍然是借用的。

let mut buffer = String::new();
io::stdin().read_line(&mut buffer).expect("failure reading stdin");
let mut info: Vec<&str> = buffer.trim().split(" ").collect(); // <-- immutable borrow of buffer
...
buffer.clear();  // <-- cannot borrow `buffer` as mutable because it is also borrowed as immutable
io::stdin().read_line(&mut buffer).expect("failure reading stdin");

我不完全确定这里发生了什么,因为我认为info会从buffer中的数据创建&str(因为&str实现了复制)。但是无论哪种方式,我都需要修改我的程序来删除这个借用。最简单的方法似乎是修改违规行,以便info拥有它包含的&str。我如何才能做到这一点?
谢谢你,

mlnl4t2r

mlnl4t2r1#

如果你想让info变成Vec<String>而不是Vec<&str>,这是可行的(Rust 1.66.1测试):

fn main() {
    let mut buffer = String::from("I am an example of a string!");
    let info: Vec<_> = buffer.trim().split(' ').map(|x| x.to_string()).collect();

    buffer.clear();

    println!("Buffer cleared. Info content: {:?}", info);
}

编辑:
请记住,str * 不 * 实现Copyhttps://doc.rust-lang.org/std/primitive.str.html
据我所知,是reference实现了Copy,所以实际上并没有得到内容的副本,只是得到了内存地址的副本。

6ioyuze2

6ioyuze22#

&str是对现有字符的引用。除非它们是静态的,否则字符必须有所有者,通常是String类型。
您的代码只有一个String,它可以拥有字符(buffer)。
例如,如果使用let info: &str = buffer.as_str()获取对String的共享引用,则不能在该引用存在时修改String。具体而言,不能在对String的任何其他引用存在时获取对String的可变引用。可变引用必须是对所拥有示例的唯一引用。
split方法返回&str的迭代器,然后将其存储在Vec中。这些&str对象中的每一个都是对所拥有的String的引用,并且只要包含它们的Vec就存在。当它们存在时,您无法获得可变引用来修改buffer
要允许修改,您需要将共享引用转换为新拥有的类型(String)以存储在Vec中,如vellista的答案所示。

相关问题