为什么在<String>调用"推送"后无法从 Vec 收集字符串?

  • 本文关键字:Vec 字符串 推送 String 调用 rust
  • 更新时间 :
  • 英文 :


我正在尝试使用分隔符$收集字符串到字符串的向量。

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("$"));
}

最新更新