Rust 中的字符串连接

Joh*_*867 3 rust

我试图让 &str 和 &str 在 for 循环中连接,目的是在添加了许多部分后使用新的组合字符串。for 循环的一般布局如下所示,但由于大量错误,我在组合字符串时遇到了很多麻烦。

for line in reader.lines() {
    let split_line = line.unwrap().split(",");
    let mut edited_line = "";

    for word in split_line {
        if !word.contains("substring") {
            let test_string = [edited_line, word].join(",");
            edited_line = &test_string;
        }
    }
    let _ = writeln!(outfile, "{}", edited_line).expect("Unable to write to file"); 
}
Run Code Online (Sandbox Code Playgroud)

第一个错误:

error[E0716]: temporary value dropped while borrowed
Run Code Online (Sandbox Code Playgroud)

运行上面的时候来。

第二个错误:

error[E0308]: mismatched types expected &str, found struct std::string::String
Run Code Online (Sandbox Code Playgroud)

当您从 test_string 中删除 & 并将其分配给edited_line 时发生

注意:format!concat!宏都给出错误 2。
似乎是如果我得到错误 2 并将其std::string:String转换为&str我得到的错误说明变量的寿命不够长。

我应该如何构建由多个部分组成的字符串?

Alo*_*oso 7

请注意,Rust 有两种字符串类型,String并且&str(实际上还有更多,但这里无关紧要)。

  • String是一个拥有的字符串,可以动态增长和收缩。
  • &str是一个借用的字符串并且是不可变的。

调用[edited_line, word].join(",")创建一个 new String,它在堆上分配。edited_line = &test_string然后借用 theString并将其隐式转换为 a &str

问题在于,一旦所有者 ( test_string) 超出范围,它的内存就会被释放,但借用的寿命比test_string. 这在 Rust 中从根本上是不可能的,因为否则它会是一个 use-after-free 错误。

正确且最有效的方法是String在循环外创建一个空的,并且只在循环中附加到它:

let mut edited_line = String::new();

for word in split_line {
    if !word.contains("substring") {
        edited_line.push(',');
        edited_line.push_str(word);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,生成的字符串将以逗号开头,这可能不是我们想要的。为了避免它,你可以写

let mut edited_line = String::new();

for word in split_line {
    if !word.contains("substring") {
        if !edited_line.is_empty() {
            edited_line.push(',');
        }
        edited_line.push_str(word);
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以用itertoolscrate更优雅地完成,它join为迭代器提供了一种方法:

use itertools::Itertools;

let edited_line: String = line
    .unwrap()
    .split(",")
    .filter(|word| !word.contains("substring"))
    .join(",");
Run Code Online (Sandbox Code Playgroud)