我正在尝试使用分隔符$
收集字符串到字符串的向量。
let v = [String::from("bump"), String::from("sage"),String::from("lol"), String::from(" kek ")];
let s: String = v.into_iter().map(|x| x.push_str("$")).collect();
println!("{:?}",s );
上面的代码不起作用,但这个:
let v = [String::from("hello"), String::from("world"),String::from("shit"), String::from(" +15 ")];
let s: String = v.into_iter().collect();
println!("{:?}",s );
正在工作。我该如何解决这个问题?
您的代码无法工作,因为push_str()
不返回字符串。
所以你的map()
函数从String
映射到()
,因为你不会从它返回x
此外,x
是不可变的,因此不能对其调用push_str()
。您必须声明它为mut
。
这是你的代码,经过最少的修改,使其正常工作:
fn main(){
let v = [String::from("bump"), String::from("sage"),String::from("lol"), String::from(" kek ")];
let s: String = v.into_iter().map(|mut x| {x.push_str("$"); x}).collect();
println!("{:?}",s );
}
"bump$sage$lol$ kek $"
此外,如果只推送单个字符,请执行push('$')
。
但是,您会注意到,在字符串的末尾有一个$
。您的用例非常适合reduce()
,所以我会使用@Aleksander的答案。
您可以使用Iterator::reduce。请注意,它将只在项之间放置分隔符(而不是像Petterrabit的答案中那样放在字符串的末尾(,并且它将重复使用第一个字符串的分配(这会提高内存效率(。
fn main() {
let v = [
String::from("bump"),
String::from("sage"),
String::from("lol"),
String::from(" kek "),
];
let s: String = v
.into_iter()
.reduce(|mut acc, x| {
acc.push('$');
acc.push_str(&x);
acc
})
.unwrap_or_default();
println!("{}", s);
}
您必须从映射中返回字符串。
请注意,push_str
不会返回任何内容。
https://play.rust-lang.org/?version=stable&mode=调试&edition=2021&gist=50534d454a6093299ce38682733c86a
fn main() {
let v = [
String::from("bump"),
String::from("sage"),
String::from("lol"),
String::from(" kek "),
];
let s: String = v
.iter()
.map(|x| {
let mut x = x.to_owned();
x.push_str("$");
x
})
.collect();
println!("{}", s);
}
编辑
如果您的真实用例更复杂,并且您必须使用迭代器和映射,那么您应该更喜欢上面的答案,这些答案做得更好(不需要拥有映射中返回的字符串,因为您无论如何都会将它们收集到一个新字符串中(。
但也就是说,如果唯一的目的是用分离器加入你的Vec,你应该简单地进行
fn main() {
let v = [
String::from("bump"),
String::from("sage"),
String::from("lol"),
String::from(" kek "),
];
println!("{}", v.join("$"));
}