rust中的字符串连接

rust中的字符串连接,rust,Rust,我试图让a&str和&str在for循环中连接起来,目的是在添加了许多部分之后使用新的组合字符串。下面可以看到for循环的总体布局,但是由于大量错误,我在组合字符串时遇到了很多困难 for line in reader.lines() { let split_line = line.unwrap().split(","); let mut edited_line = ""; for word in split_line {

我试图让a&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"); 
}
第一个错误:

error[E0716]: temporary value dropped while borrowed
运行上述命令时出现

第二个错误:

error[E0308]: mismatched types expected &str, found struct std::string::String
在将测试_字符串指定给已编辑的_行时从中删除(&F)时发生

注意:
格式
concat宏都会给出错误2。
如果我得到错误2并将
std::string:string
转换为
&str
,我会得到一个错误,说明变量的寿命不够长


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

让mut编辑_line=“”
使
编辑的行
a
&str
具有静态生存期

要实际将
编辑的\u行
作为字符串,请将
附加到\u owned()
,或使用
字符串::new()

看看你是否不熟悉这些差异

最重要的是,您不能扩展
&str
,但可以扩展
字符串


一旦您将已编辑的行切换为
字符串
,请使用将
已编辑的行
设置为
[已编辑的行,word]的方法。连接(“,”工作:

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

    for word in split_line {
        if !word.contains("substring") {
            let test_string = [edited_line.as_str(), word].join(","); // Added .as_str() to edited_line
            edited_line = test_string; // Removed the & here
        }
    }
    let _ = writeln!(outfile, "{}", edited_line).expect("Unable to write to file"); 
}

然而,这既不是很有效,也不符合人体工程学。它还有一个(可能是意外的)结果,即在每行前面加上一个


下面是一个仅使用一个
字符串
实例的替代方案:

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

    for word in split_line {
        if !word.contains("substring") {
            edited_line.push(',');
            edited_line.push_str(word);
        }
    }
    let _ = writeln!(outfile, "{}", edited_line).expect("Unable to write to file"); 
}
但是,这仍然会在每行前面加上
字符。在按下
之前,您可以通过检查编辑的行是否为空来修复此问题


第三个选项是将for循环更改为迭代器:

for line in reader.lines() {
    let edited_line = line.split(",")
        .filter(|word| !word.contains("substring"))
        .collect::<Vec<&str>>() // Collecting allows us to use the join function.
        .join(",");
    let _ = writeln!(outfile, "{}", edited_line).expect("Unable to write to file"); 
}
读取器中的行的
。行(){
让编辑的线=线。拆分(“,”)
.filter(| word |!word.contains(“子字符串”))
.collect::()//collection允许我们使用join函数。
.加入(“,”);
让{=writeln!(输出文件,{},编辑行)。预期(“无法写入文件”);
}

通过这种方式,我们可以按预期使用join函数,巧妙地消除每行开头的初始



PS:如果您不知道每个变量是什么类型,我建议使用类似IDE的工具,在编写它们时为每个变量显示类型提示。

let mut edited_line=“”
使
编辑的行
a
&str
具有静态生存期

要实际将
编辑的\u行
作为字符串,请将
附加到\u owned()
,或使用
字符串::new()

看看你是否不熟悉这些差异

最重要的是,您不能扩展
&str
,但可以扩展
字符串


一旦您将已编辑的行切换为
字符串
,请使用将
已编辑的行
设置为
[已编辑的行,word]的方法。连接(“,”工作:

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

    for word in split_line {
        if !word.contains("substring") {
            let test_string = [edited_line.as_str(), word].join(","); // Added .as_str() to edited_line
            edited_line = test_string; // Removed the & here
        }
    }
    let _ = writeln!(outfile, "{}", edited_line).expect("Unable to write to file"); 
}

然而,这既不是很有效,也不符合人体工程学。它还有一个(可能是意外的)结果,即在每行前面加上一个


下面是一个仅使用一个
字符串
实例的替代方案:

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

    for word in split_line {
        if !word.contains("substring") {
            edited_line.push(',');
            edited_line.push_str(word);
        }
    }
    let _ = writeln!(outfile, "{}", edited_line).expect("Unable to write to file"); 
}
但是,这仍然会在每行前面加上
字符。在按下
之前,您可以通过检查编辑的行是否为空来修复此问题


第三个选项是将for循环更改为迭代器:

for line in reader.lines() {
    let edited_line = line.split(",")
        .filter(|word| !word.contains("substring"))
        .collect::<Vec<&str>>() // Collecting allows us to use the join function.
        .join(",");
    let _ = writeln!(outfile, "{}", edited_line).expect("Unable to write to file"); 
}
读取器中的行的
。行(){
让编辑的线=线。拆分(“,”)
.filter(| word |!word.contains(“子字符串”))
.collect::()//collection允许我们使用join函数。
.加入(“,”);
让{=writeln!(输出文件,{},编辑行)。预期(“无法写入文件”);
}

通过这种方式,我们可以按预期使用join函数,巧妙地消除每行开头的初始



PS:如果您不知道每个变量是什么类型,我建议使用类似IDE的工具,在编写它们时为每个变量显示类型提示。

请注意,Rust有两种字符串类型,
string
&str
(实际上,还有更多,但这与此无关)

  • 字符串
    拥有的字符串,可以动态地增长和收缩
  • &str
    是借用的字符串,是不可变的
调用
[edited_line,word].join(“,”
将创建一个新的
字符串,该字符串在堆上分配
edited_line=&test_string
然后借用
字符串
,并将其隐式转换为
&str

问题是,一旦所有者(
test\u string
)超出范围,它的内存就会被释放,但借用的寿命长于
test\u string
。这在生锈的情况下基本上是不可能的,因为它在释放bug后会被使用

正确且最有效的方法是在循环外部创建一个空的
字符串
,并仅在循环中追加:

let mut edited_line=String::new();
对于拆分行中的单词{
if!word.contains(“子字符串”){
编辑的_行。推送(',');
编辑行。推送字符串(word);
}
}
请注意,结果字符串将以逗号开头,这可能是不需要的。为了避免它,你可以写

let mut edited_line=String::new();
对于拆分行中的单词{
if!word.contains(“子字符串”){
如果!已编辑的\u行为空(){
编辑的_行。推送(',');
}
编辑行。推送字符串(word);
}
}
这可以通过板条箱更优雅地完成,它为迭代器提供了一种
join
方法:

使用itertools::Itertoo