2016-06-21 10 views
1

Ich bin über eine HashMap iterieren und setzen Sie die Werte über Mustervergleich in einigen lokalen vars.Warum ergibt das Iterieren über eine HashMap <&str,&str> eine && str?

Delegater

fn lyrics_no_bottles(song_template:&mut String){ 
    let mut template_partials = HashMap::new(); 

    template_partials.insert("start", "No more bottles"); 
    template_partials.insert("repeat", "no more bottles"); 
    template_partials.insert("remaining", "99 bottles"); 
    template_partials.insert("message", "Go to the store and buy some more"); 

    resolve_template(song_template, template_partials); 
} 

Called

fn resolve_template(song_template:&mut String, partials: HashMap<&str, &str>){ 
    let start:&str; 
    let repeat:&str; 
    let remaining:&str; 
    let message:&str; 

    for key in partials.keys(){ 
     match key { 
      "start" => start = partials.get(key), 
      "repeat" => repeat = partials.get(key), 
      "remaining" => remaining = partials.get(key), 
      "message" => message = partials.get(key) 
     } 
    } 

    *song_template = song_template.replace("%1", start); 
    *song_template = song_template.replace("%2", repeat); 
    *song_template = song_template.replace("%3", message); 
    *song_template = song_template.replace("%4", remaining); 
} 

Fehlerausgabe

lib.rs:51:5: 58:6 error: type mismatch resolving `<std::collections::hash::map::Keys<'_, &str, &str> as core::iter::Iterator>::Item == &str`: 
expected &-ptr, 
    found str [E0271] 
lib.rs:51  for key in partials.keys(){ 
lib.rs:52   match key { 
lib.rs:53    "start" => start = partials.get(key), 
lib.rs:54    "repeat" => repeat = partials.get(key), 
lib.rs:55    "remaining" => remaining = partials.get(key), 
lib.rs:56    "message" => message = partials.get(key) 
      ... 
lib.rs:51:5: 58:6 help: run `rustc --explain E0271` to see a detailed explanation 
lib.rs:53:32: 53:49 error: mismatched types: 
expected `&str`, 
    found `core::option::Option<&&str>` 
(expected &-ptr, 
    found enum `core::option::Option`) [E0308] 
lib.rs:53    "start" => start = partials.get(key), 

ich nicht underst und warum der Compiler denkt, dass es einen &&str gibt, als ich den Parameter als HashMap<&str,&str> deklarierte.

Antwort

3

Weil that particular method returns a reference wrapped by an Option.

Grundsätzlich, wenn Sie einen String speichern es und verwenden get .. Sie werden eine Option<&String> als Ergebnis eines Aufrufs zu get bekommen. Wenn Sie &str speichern, erhalten Sie eine Option<&&str> als Ergebnis eines Anrufs an get.

Beispiele für Werte und wie sie werden angezeigt, wenn Sie get nennen:

String -> Option<&String> 
&str -> Option<&&str> 
u32 -> Option<&u32> 

Eigentümer des &str zum hashmap übertragen wird, wenn Sie es in als Wert ein. Die hashmap gibt daher für sie Referenzen zurück, die get ... oder mutable references using get_mut verwenden.

Der Spielplatz ist derzeit defekt (kann nichts von ihm teilen) ... so ist hier eine Arbeits .. aufgeschlüsselt Probe des Codes:

use std::collections::HashMap; 

fn main() { 
    let mut map: HashMap<&str, &str> = HashMap::new(); 
    map.insert("start", "value"); 

    let mut start: &str = "Unknown"; 
    let mut repeat: &str; 
    let mut remaining: &str; 
    let mut message: &str; 

    for key in map.keys() { 
     match &key[..] { 
      "start" => start = map.get(key).unwrap(), 
      "repeat" => repeat = map.get(key).unwrap(), 
      "remaining" => remaining = map.get(key).unwrap(), 
      "message" => message = map.get(key).unwrap(), 
      _ => unreachable!() 
     } 
    } 

    println!("Result: {}", start); 
} 
+0

So zerstören muss ich auch die 'Option <&&str> 'bevor ich sogar das' && str' aufheben kann ... Ich werde versuchen ein 'if Let Some (x)' – xetra11

+0

Richtig. Vielleicht sollte ich Ihnen auch in meiner Antwort eine Lösung für Ihr tatsächliches Problem geben. Ich füge das jetzt hinzu. –

+0

danke ... bekomme ich es nicht mit zu arbeiten, wenn es trotzdem erlaubt – xetra11