2016-05-12 77 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(()) 
}