如何在生锈中使用Iterator的#map和#fold?

时间:2014-10-27 19:32:22

标签: iterator rust

rustc 0.13.0-nightly (f168c12c5 2014-10-25 20:57:10 +0000)

我有以下代码。

fn main() {
  let nums = vec![1i,2,3];

  let strings = nums.iter()
  .map(|n| n.to_string())
  .fold(String::new, |a, b| a.push_str(b.as_slice()));

  assert_eq!("123", strings.as_slice());
}

它应该将nums中的整数转换为它们的字符串表示形式,并将它们连接到一个大字符串。

这是我从rustc得到的东西:

test2.rs:6:31: 6:53 error: type `fn() -> collections::string::String` does not implement any method in scope named `push_str`
test2.rs:6   .fold(String::new, |a, b| a.push_str(b.as_slice()));
                                         ^~~~~~~~~~~~~~~~~~~~~~
test2.rs:8:29: 8:39 error: type `fn() -> collections::string::String` does not implement any method in scope named `as_slice`
test2.rs:8   assert_eq!("123", strings.as_slice());
                                       ^~~~~~~~~~
<std macros>:6:23: 6:33 error: the type of this value must be known in this context
<std macros>:6                 if !((*given_val == *expected_val) &&
                                     ^~~~~~~~~~
<std macros>:1:1: 14:2 note: in expansion of assert_eq!
test2.rs:8:3: 8:41 note: expansion site
<std macros>:6:23: 6:33 error: the type of this value must be known in this context
<std macros>:6                 if !((*given_val == *expected_val) &&
                                     ^~~~~~~~~~
<std macros>:1:1: 14:2 note: in expansion of assert_eq!
test2.rs:8:3: 8:41 note: expansion site
<std macros>:6:37: 6:50 error: the type of this value must be known in this context
<std macros>:6                 if !((*given_val == *expected_val) &&
                                                   ^~~~~~~~~~~~~
<std macros>:1:1: 14:2 note: in expansion of assert_eq!
test2.rs:8:3: 8:41 note: expansion site
<std macros>:7:23: 7:36 error: the type of this value must be known in this context
<std macros>:7                      (*expected_val == *given_val)) {
                                     ^~~~~~~~~~~~~
<std macros>:1:1: 14:2 note: in expansion of assert_eq!
test2.rs:8:3: 8:41 note: expansion site
error: aborting due to 6 previous errors

所以它抱怨类型fn() -> collections::string::String,但我期待地图的结果只是普通的collections::string::String

我在这里做错了什么,或者地图不应该像我在示例中尝试的那样使用?

修改

哈哈,我发现错误,String::newfn() -> collections::string::String,所以这是一个错字!

正确是.fold(String::new(), |a, b| a.push_string(b.as_slice()));

1 个答案:

答案 0 :(得分:5)

有3个问题:

  1. String::new缺少(),应该是String::new()
  2. 您必须从折叠结束返回一个新状态,push_str返回()
  3. 您必须使状态变为可变,以便可以使用push_str

  4. fn main() {
      let nums = vec![1i,2,3];
    
      let strings = nums.iter()
      .map(|n| n.to_string())
      .fold(String::new(), |mut a, b| {
            a.push_str(b.as_slice());
            a
        });
    
      assert_eq!("123", strings.as_slice());
    }