2016-05-12 4 views
3

Ich versuche, die "Tuple-Lektionen" auf der Rust by Example website zu übergeben, aber ich bin auf der formatierten Ausgabe Implementierung stecken. Ich habe diesen Code, der die übergebene Matrix druckt:Get String als Wert in der formatierten Ausgabe

#[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) 
    } 
} 

Aber der Compiler druckt die nächste Nachricht:

<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 

Ich habe versucht output_data zu wickeln ‚s in eine RefCell führen, aber die complier druckt immer noch diesen Fehler. Wie kann ich dieses Problem beheben, sodass das Makro ordnungsgemäß funktioniert?

Antwort

5

Das Problem ist, dass into_inter das Eigentum an data nimmt, das heißt, ist data von self ausziehen, und das nicht erlaubt ist (das ist, was der Fehler sagt). Um ohne dabei das Eigentum in einem Vektor iterieren, verwenden iter Methode:

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

Werfen Sie einen Blick auf Formatter. Es hat einige Methoden zum Schreiben fmt. Hier ist eine Version, die Vermittler Vektoren und Strings nicht zuweist:

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