rust中的字符串连接
我试图让a&str和&str在for循环中连接起来,目的是在添加了许多部分之后使用新的组合字符串。下面可以看到for循环的总体布局,但是由于大量错误,我在组合字符串时遇到了很多困难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 {
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