2016-05-12 82 views
3

我試圖通過Rust by Example website上的「Tuple課程」,但我被卡在格式化的輸出實現上。我有這樣的代碼,它打印傳遞矩陣:獲取字符串作爲格式化輸出中的值

#[derive(Debug)] 
struct Matrix{ 
    data: Vec<Vec<f64>> // [[...], [...],] 
} 

impl fmt::Display for Matrix { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     let output_data = self.data 
      // [[1, 2], [2, 3]] -> ["1, 2", "2, 3"] 
      .into_iter() 
      .map(|row| { 
       row.into_iter() 
        .map(|value| value.to_string()) 
        .collect::<Vec<String>>() 
        .join(", ") 
      }) 
      .collect::<Vec<String>>() 
      // ["1, 2", "2, 3"] -> ["(1, 2)", "(2, 3)"] 
      .into_iter() 
      .map(|string_row| { format!("({})", string_row) }) 
      // ["(1, 2)", "(2, 3)"] -> "(1, 2),\n(2, 3)" 
      .collect::<Vec<String>>() 
      .join(",\n"); 
     write!(f, "{}", output_data) 
    } 
} 

但是,編譯器打印一條消息:

<anon>:21:40: 21:44 error: cannot move out of borrowed content [E0507] 
<anon>:21   let output_data = self.data 
            ^~~~ 
<anon>:21:40: 21:44 help: see the detailed explanation for E0507 
error: aborting due to previous error 
playpen: application terminated with error code 101 

我試着換output_data的成績爲RefCell,但編譯仍然打印此錯誤。我如何解決這個問題,以便write!宏能夠正常工作?

回答

5

的問題是,into_inter需要的data的所有權,也就是說,從self搬出data,那是不允許的(即錯誤說什麼)。在沒有取得所有權的向量迭代,用iter方法:

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
    let output_data = self.data 
     // [[1, 2], [2, 3]] -> ["1, 2", "2, 3"] 
     .iter() 
     .map(|row| { 
      row.into_iter() 
       .map(|value| value.to_string()) 
       .collect::<Vec<String>>() 
       .join(", ") 
     }) 
     .collect::<Vec<String>>() 
     // ["1, 2", "2, 3"] -> ["(1, 2)", "(2, 3)"] 
     .into_iter() 
     .map(|string_row| { format!("({})", string_row) }) 
     // ["(1, 2)", "(2, 3)"] -> "(1, 2),\n(2, 3)" 
     .collect::<Vec<String>>() 
     .join(",\n"); 
    write!(f, "{}", output_data) 
} 

看看Formatter。它有一些方法可以幫助編寫fmt。這是一個不分配媒介向量和字符串的版本:

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
    let mut sep = ""; 
    for line in &self.data { // this is like: for line in self.data.iter() 
     try!(f.write_str(sep)); 
     let mut d = f.debug_tuple(""); 
     for row in line { 
      d.field(row); 
     } 
     try!(d.finish()); 
     sep = ",\n"; 
    } 
    Ok(()) 
}