Rust 字符串连接 [英] Rust String concatenation
问题描述
我本周开始使用 Rust 进行编程,但在理解字符串的工作方式时遇到了很多问题.
I started programming with Rust this week and I am having a lot of problems understanding how Strings work.
现在,我正在尝试做一个简单的程序来打印附加他们订单的玩家列表(仅用于学习目的).
Right now, I am trying to do a simple program that prints a list of players appending their order(for learning purposes only).
let res : String = pl.name.chars().enumerate().fold(String::new(),|res,(i,ch)| -> String {
res+=format!("{} {}\n",i.to_string(),ch.to_string());
});
println!("{}", res);
这是我的想法,我知道我可以只使用 for 循环,但目标是了解不同的 Iterator 函数.
This is my idea, I know I could just use a for loop but the objective is to understand the different Iterator functions.
所以,我的问题是字符串连接不起作用.
So, my problem is that the String concatenation does not work.
Compiling prueba2 v0.1.0 (file:///home/pancho111203/projects/prueba2)
src/main.rs:27:13: 27:16 error: binary assignment operation `+=` cannot be applied to types `collections::string::String` and `collections::string::String` [E0368]
src/main.rs:27 res+=format!("{} {}\n",i.to_string(),ch.to_string());
^~~
error: aborting due to previous error
Could not compile `prueba2`.
我尝试使用 &str 但无法从 i
和 ch
值创建它们.
I tried using &str but it is not possible to create them from i
and ch
values.
推荐答案
首先,在 Rust 中 x += y
是不可重载的,所以 +=
操作符不会适用于除基本数字类型之外的任何内容.然而,即使它适用于字符串,它也等价于 x = x + y
,如下所示:
First, in Rust x += y
is not overloadable, so +=
operator won't work for anything except basic numeric types. However, even if it worked for strings, it would be equivalent to x = x + y
, like in the following:
res = res + format!("{} {}\n",i.to_string(),ch.to_string())
即使类型系统允许这样做(不是因为 String + String
在 Rust 中没有定义重载"),这仍然不是 fold()
操作.你想要这个:
Even if this were allowed by the type system (it is not because String + String
"overload" is not defined in Rust), this is still not how fold()
operates. You want this:
res + &format!("{} {}\n", i, ch)
或者,作为一个可编译的例子,
or, as a compilable example,
fn main(){
let x = "hello";
let res : String = x.chars().enumerate().fold(String::new(), |res, (i, ch)| {
res + &format!("{} {}\n", i, ch)
});
println!("{}", res);
}
当你执行折叠时,你不重新分配累加器变量,你需要返回新值以便在下一次迭代中使用,这正是res + format!(...)
做.
When you perform a fold, you don't reassign the accumulator variable, you need to return the new value for it to be used on the next iteration, and this is exactly what res + format!(...)
do.
请注意,我删除了 to_string()
调用,因为它们完全没有必要——事实上,x.to_string()
等效于 format!("{}", x)
,所以你只在这里执行不必要的分配.
Note that I've removed to_string()
invocations because they are completely unnecessary - in fact, x.to_string()
is equivalent to format!("{}", x)
, so you only perform unnecessary allocations here.
此外,我通过引用获取 format!()
结果:&format!(...)
.这是必要的,因为 +
字符串的重载"是为 String + &str
类型定义的,所以你需要从 String
转换(format!()
的结果)到 &str
,这可以通过在这里使用 &
来完成(因为 deref强制).
Additionally, I'm taking format!()
result by reference: &format!(...)
. This is necessary because +
"overload" for strings is defined for String + &str
pair of types, so you need to convert from String
(the result of format!()
) to &str
, and this can be done simply by using &
here (because of deref coercion).
事实上,以下方法会更有效:
In fact, the following would be more efficient:
use std::fmt::Write;
fn main(){
let x = "hello";
let res: String = x.chars().enumerate().fold(String::new(), |mut res, (i, ch)| {
write!(&mut res, "{} {}\n", i, ch).unwrap();
res
});
println!("{}", res);
}
可以更习惯地写成
use std::fmt::Write;
fn main(){
let x = "hello";
let mut res = String::new();
for (i, ch) in x.chars().enumerate() {
write!(&mut res, "{} {}\n", i, ch).unwrap();
}
println!("{}", res);
}
(在 playpen 上试试)
这种方式不会创建额外的分配(即来自 format!()
的新字符串).我们只是用新数据填充字符串,例如,与 Java 中 StringBuilder
的工作方式非常相似.use std::fmt::Write
这里需要允许在 &mut String
上调用 write!()
.
This way no extra allocations (i.e. new strings from format!()
) are created. We just fill the string with the new data, very similar, for example, to how StringBuilder
in Java works. use std::fmt::Write
here is needed to allow calling write!()
on &mut String
.
我还建议阅读官方 Rust 书中的关于字符串的章节(以及这本书作为如果您是 Rust 的新手,则是一个整体).它解释了 String
和 &str
是什么,它们有何不同以及如何有效地使用它们.
I would also suggest reading the chapter on strings in the official Rust book (and the book as a whole if you're new to Rust). It explains what String
and &str
are, how they are different and how to work with them efficiently.
这篇关于Rust 字符串连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!