2016-01-07 5 views
5

Ich bin neu in Rust und suche Konzepte wie das Ausleihen zu verstehen. Ich versuche, ein einfaches zweidimensionales Array mit Standardeingabe zu erstellen. Der Code:Wie man iteriert und Werte aus einer for-Schleife in Rust extrahiert

use std::io; 

fn main() { 
    let mut values = [["0"; 6]; 6]; // 6 * 6 array 

    // iterate 6 times for user input 
    for i in 0..6 { 
     let mut outputs = String::new(); 
     io::stdin().read_line(&mut outputs).expect(
      "failed to read line", 
     ); 

     // read space separated list 6 numbers. Eg: 5 7 8 4 3 9 
     let values_itr = outputs.trim().split(' '); 
     let mut j = 0; 
     for (_, value) in values_itr.enumerate() { 
      values[i][j] = value; 
      j += 1; 
     } 
    } 
} 

Dies kompiliert nicht, weil die outputs Variable Lebensdauer nicht lang genug ist:

error[E0597]: `outputs` does not live long enough 
    --> src/main.rs:20:5 
    | 
14 |   let values_itr = outputs.trim().split(' '); 
    |       ------- borrow occurs here 
... 
20 |  } 
    | ^`outputs` dropped here while still borrowed 
21 | } 
    | - borrowed value needs to live until here 

Wie kann ich die iterierten Werte aus dem Block in Werte Array bekommen?

Antwort

6

split() gibt Ihnen Strings (string Scheiben) aus der ursprünglichen Zeichenkette ausgeliehen, und die ursprüngliche Zeichenfolge ist outputs von der Linie 6.

  1. Der String Scheiben können den Umfang der outputs nicht überleben: Wenn ein Schleifeniterationslatenzzeit endet, outputs wird freigegeben. Da values länger lebt, können die Scheiben dort nicht gelagert werden.
  2. Wir können keine Scheiben von outputs über eine Modifikation von outputs ausleihen. Selbst wenn die Stringoutputs selbst vor values definiert wurde, konnten wir die String-Slices nicht einfach von .split() in values einfügen; Durch Ändern der Zeichenfolge (Einlesen) werden die Slices ungültig.

Eine Lösung muss entweder

  • ein verschachteltes Array von String verwenden, und wenn man ein Element aus der Iterator Split zuzuweisen, eine String vom &str Verwendung .to_string() machen. Ich würde diese Lösung empfehlen. (Jedoch eine Reihe von String ist nicht so einfach, mit zu arbeiten, vielleicht schon erfordert dies mit Vec statt.)
  • alle Eingaben lesen, bevor sie eine verschachtelte Anordnung von &str konstruieren, das String aus dem Eingang leiht. Dies ist nützlich, wenn das verschachtelte Array nur vorübergehend benötigt wird.

: Sie so etwas wie vec![vec![String::new(); 6]; 6] statt

+0

Es wäre ideal, wenn ich das mit Arrays lösen kann. Aber anscheinend gibt es keine Möglichkeit, in Rust ein Array von Strings zu erstellen. Ist es nicht? Die erste Methode funktioniert gut mit den Vektoren. Danke für die Antwort .. (einschließlich Ihrer letzten Bemerkungen zu IRC) "value ist a & str, ein Teilstring von outputs. So .to_string() reserviert Platz für einen String und kopiert den Teilstring in diesen. So Wert war ein & str (a Referenz) aber in einen String umgewandelt wird, da es keine Referenz ist, wird es nicht durch den Border Checker oder die Lebensdauer von 'Outputs 'eingeschränkt." – vimukthi

+0

Es gibt keine * nette * Möglichkeit, ein Array von Strings zu erstellen. '[[String :: new(), String :: new(), String :: new(), String :: new(), String :: new(), String :: new()], [String :: new(), String :: new(), String :: new(), String :: new(), String :: new(), String :: new()], ...] ist sicherlich nicht nett . – bluss

1

Diese Antwort von der Frage bewegt wurde verwenden können, wo es die OPs Bedürfnisse gelöst.

use std::io; 

fn main() { 
    let mut values = vec![vec![String::new(); 6]; 6]; 
    for i in 0..6 { 
     let mut outputs = String::new(); 
     io::stdin().read_line(&mut outputs) 
       .expect("failed to read line"); 

     let values_itr = outputs.trim().split(' '); 
     let mut j = 0; 
     for (_, value) in values_itr.enumerate() { 
      values[i][j] = value.to_string(); 
      j += 1; 
     } 
    } 
} 
Verwandte Themen