2014-10-27 26 views
0

rustc 0.13.0-nightly (f168c12c5 2014-10-25 20:57:10 +0000)如何使用Iterator的#map和#fold生鏽?

我有以下代碼。

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

回答

4

有3個問題:

  1. String::new缺少(),並應String::new()
  2. 你必須返回一個新的狀態從襞閉合,push_str返回()
  3. 你必須使狀態可變,所以你可以使用它push_str

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()); 
} 
+0

的感謝!一個問題:str.push_str(other)和str + other之間是否存在性能差異? – 2014-10-27 19:43:58

+0

@le_me:是的,使用'+'分配給每個加法的新字符串 – Arjan 2014-10-27 19:46:44