7

我无法弄清楚如何以~str惯用的方式使用带有类型键的 HashMap。例如,

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");

基于错误报告,我尝试了

map.contains_key_equiv("hello");

但得到了

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

我真的不明白这最后一条信息;有人有建议吗?

4

2 回答 2

4

你有HashMap<K, V>with ~str(an own string) as K; 因此,它想要&Kfor 的地方things&~str——对拥有的字符串的引用。但是,您正在向它传递对静态字符串的引用(没有任何符号 [ &,~等的字符串文字,"hello", 是 类型&'static str)。

对于字符串文字,不要使用.to_str(); 相反,用~, 作为前缀~"hello"。像这样的字符串文字属于~str. 对于非文字,您通常应该.to_owned()使用&str.

最终的代码可以这样操作:

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

请注意,当您需要对引用的引用时,您不能这样做&&,因为这是布尔 AND 运算符;你需要做&(&x)& &x

(另请注意,三个月前的任何问题都可能不是最新的;我不确定 HashMap 比较技术的当前状态 - 尝试两种方式,使用正确的类型。)

于 2013-07-29T03:57:37.143 回答
3

的声明contains_key_equiv是:

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

也就是说,它引用了EquivK == ~str. 因此,要检查 a &str(它是Equivalent to ~str),我们需要 a & &str(对字符串切片的引用)。

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

// or

map.contains_key_equiv(& &"hello");

(请注意,它们是等价的,只是为了绕过"foo" == &"foo"两者都是&strs 的事实。)

于 2013-07-29T12:22:11.147 回答