附加到for循环内的字符串

ujh*_*ujh 3 rust

我试图通过在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)

Vla*_*eev 8

更新:在最新的Rust(从1.0.0-alpha开始)append()方法不再存在.然而,无论是StringVec+方法重载,它表现得完全像老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()是绝对正确的.


A.B*_*.B. 7

函数签名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)作为迭代器进行折叠.