2013-07-28 16 views
5

Ich habe Probleme herauszufinden, wie man eine HashMap mit einem Schlüssel des Typs ~str idiomatisch verwendet. Zum BeispielString-keyed HashMap in Rost?

let mut map: hashmap::HashMap<~str, int> = hashmap::HashMap::new(); 
// Inserting is fine, I just have to copy the string. 
map.insert("hello".to_str(), 1); 

// If I look something up, do I really need to copy the string? 
// This works: 
map.contains_key(&"hello".to_str()); 

// This doesn't: as expected, I get 
// error: mismatched types: expected `&~str` but found `&'static str` (expected &-ptr but found &'static str) 
map.contains_key("hello"); 

Basierend auf this Bug-Report habe ich versucht,

map.contains_key_equiv("hello"); 

bekam aber

error: mismatched types: expected `&<V367>` but found `&'static str` (expected &-ptr but found &'static str) 

Ich weiß nicht wirklich, diese letzte Nachricht verstehen; Hat jemand einen Vorschlag?

Antwort

3

Die Deklaration contains_key_equiv ist:

pub fn contains_key_equiv<Q:Hash + Equiv<K>>(&self, key: &Q) -> bool 

das heißt, es braucht einen Verweis auf etwas, das Equiv Alent zu K == ~str ist. Um nach einem &str (also Equiv alent zu ~str) zu suchen, wollen wir einen & &str (eine Referenz zu einem String-Slice).

map.contains_key_equiv(&("hello")); 

// or 

map.contains_key_equiv(& &"hello"); 

(Beachten Sie, dass diese äquivalent sind, und sind nur um die Tatsache zu erhalten erforderlich, dass "foo" == &"foo" sind beide &str s.)

3

Sie haben HashMap<K, V> mit ~str (einer hundertprozentigen string) als K; Also, wo es &K für things will, das ist &~str — ein Verweis auf eine eigene Zeichenfolge. Sie übergeben jedoch einen Verweis auf eine statische Zeichenfolge (ein Zeichenfolgenliteral ohne Zeichen [&, ~ usw.], "hello", ist vom Typ &'static str).

Verwenden Sie für Zeichenfolgenliterale nicht .to_str(); Stellen Sie es stattdessen mit ~, wie ~"hello". Ein String-Literal wie dieses ist vom Typ ~str. Für ein nicht literales Format sollten Sie normalerweise .to_owned() eines &str verwenden.

Die eventuelle Code kann wie folgt funktionieren:

use std::hashmap::HashMap; 

fn main() { 
    let mut h = HashMap::new::<~str, int>(); 
    h.insert(~"foo", 42); 
    printfln!("%?", h.find(&~"foo")); // => Some(&42) 
    printfln!("%?", h.contains_key(&~"foo")); // => true 

    // You don’t actually need the HashMap to own the keys (but 
    // unless all keys are 'static, this will be likely to lead 
    // to problems, so I don’t suggest you do it in reality) 
    let mut h = HashMap::new::<&str, int>(); 
    h.insert("foo", 42); 
    printfln!("%?", h.find(& &"foo")); // => Some(&42) 
} 

Beachten Sie, dass, wenn Sie einen Verweis auf eine Referenz benötigen Sie nicht && tun können, als dass der Boolesche AND-Operator ist; Sie müssen &(&x) oder & &x tun.

(Beachten Sie auch, dass jede Ausgabe von vor drei Monaten nicht mehr aktuell sein kann;. Ich bin nicht sicher über den aktuellen Stand der HashMap des Vergleichstechnik in beiden Richtungen — versuchen, mit den richtigen Typen)