我试图通过在for循环中追加它来构建一个字符串.由于某种原因,字符串被移动到for循环中,我无法让它工作.我显然错过了一些东西.这是一个展示此行为的简短代码段:
fn main() {
let s = format!("some string");
for x in vec!(1,2).move_iter() {
s.append("some other string");
}
}
Run Code Online (Sandbox Code Playgroud)
我从编译器(rustc 0.11.0-pre (c0a6f72 2014-06-12 14:17:13 +0000))得到以下错误:
test.rs:4:9: 4:10 error: use of moved value: `s`
test.rs:4 s.append("some other string");
^
test.rs:4:9: 4:10 note: `s` moved here because it has type `collections::string::String`, which is non-copyable (perhaps you meant to use clone()?)
test.rs:4 s.append("some other string");
^
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
更新:在最新的Rust(从1.0.0-alpha开始)append()方法不再存在.然而,无论是String和Vec已+方法重载,它表现得完全像老append():
let s = String::new() + "some part" + "next part";
Run Code Online (Sandbox Code Playgroud)
运算符总是按值来获取它们的操作数,因此这不会导致不必要的重新分配.正确的操作数必须是&strfor String或&[T]for Vec<T>; 在后一种情况下,T必须是Clone.
无论如何,push_str()仍然可用.
你得到这个错误的原因是你使用了错误的方法:)
String::append()方法是建设者般的; 它应该像这样使用:
let s = String::new()
.append("some part")
.append("next part");
Run Code Online (Sandbox Code Playgroud)
实际上,您可以在代码中使用它:
let mut s = "some string".to_string();
for &x in [1, 2].iter() {
s = s.append("some other string"); // note the reassignment
}
Run Code Online (Sandbox Code Playgroud)
这是因为append()有这个签名:
fn append(self, other: &str) -> String { ... }
Run Code Online (Sandbox Code Playgroud)
也就是说,它按值接收接收器,并将其移入呼叫中.它允许轻松链接,但如果您需要修改现有变量,则有些不方便.
您正在寻找的方法称为push_str():
let mut s = "some string".to_string();
for &x in [1, 2].iter() {
s.push_str("some other string");
}
Run Code Online (Sandbox Code Playgroud)
它只是将传递的字符串切片附加到现有的String.请注意,您还必须标记s为可变.你也不需要分配新的vector vec!(),静态数组就足够了.
也就是说,如果可能的话,最好完全避免突变.@ AB的建议使用fold()是绝对正确的.
函数签名append是
fn append(self, second: &str) -> String
Run Code Online (Sandbox Code Playgroud)
self是按值传递的,这意味着如果自己实现了复制特征,它将被复制,否则它将被移动.String不实现Copy,因此它将被移动.
折叠操作可以在追加之间保持字符串:
let s = format!("some string");
let s = vec!(1,2).iter()
.fold(s, |s, num| s.append("some other string"));
println!("{}",s);
Run Code Online (Sandbox Code Playgroud)
我假设你最终想从向量中读取字符串.如果您只是尝试多次重复操作,则应使用range(0, n)或std::iter::Repeat::new("some other string").take(n)作为迭代器进行折叠.