附加到for循环内的字符串

时间:2014-06-13 07:43:33

标签: rust

我正在尝试通过在for循环中附加到它来构建字符串。由于某种原因,字符串被移动到for循环中,我无法让它工作。我显然错过了一些东西。这是一段显示此行为的简短代码段:

fn main() {
  let s = format!("some string");
  for x in vec!(1,2).move_iter() {
    s.append("some other string");
  }
}

我从编译器(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

2 个答案:

答案 0 :(得分:8)

更新:在最新的Rust(从1.0.0-alpha开始)append()方法不再存在。但是,StringVec都有+方法重载,其行为与旧append()完全相同:

let s = String::new() + "some part" + "next part";

运算符总是按值来获取操作数,因此不会导致不必要的重新分配。对于&str,右操作数必须为String;对于&[T],{1}}必须为Vec<T>;在后一种情况下,T必须为Clone

无论如何,push_str()仍然可用。


您收到此错误的原因是您使用了错误的方法:)

String::append()方法类似于构建器;它应该像这样使用:

let s = String::new()
    .append("some part")
    .append("next part");

事实上,您可以在代码中使用它:

let mut s = "some string".to_string();
for &x in [1, 2].iter() {
    s = s.append("some other string");  // note the reassignment
}

这是因为append()有此签名:

fn append(self, other: &str) -> String { ... }

也就是说,它按值接收接收器,并将其移入呼叫中。它允许轻松链接,但如果您需要修改现有变量,则有些不方便。

您正在寻找的方法称为push_str()

let mut s = "some string".to_string();
for &x in [1, 2].iter() {
    s.push_str("some other string");
}

它只是将传递的字符串切片附加到现有的String。请注意,您还必须将s标记为可变。您也不需要使用vec!()分配新的向量,静态数组就足够了。

尽管如此,如果可能的话,最好完全避免突变。 @ A.B。建议使用fold()是绝对正确的。

答案 1 :(得分:7)

append的功能签名是

fn append(self, second: &str) -> String

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);

我假设你最终想从向量中读取字符串。如果您只是尝试多次重复操作,则应使用range(0, n)std::iter::Repeat::new("some other string").take(n)作为迭代器来进行折叠。