【问题标题】:String-keyed HashMap in rust?生锈的字符串键控HashMap?
【发布时间】:2013-07-28 21:23:23
【问题描述】:

我无法弄清楚如何以惯用的方式使用带有~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");

基于this 错误报告,我尝试过

map.contains_key_equiv("hello");

但是得到了

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

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

【问题讨论】:

  • 这个问题现在已经过时了;感谢Borrow trait,将代码简单翻译成当前语法和方法名称就可以正常工作,没有错误。

标签: hashmap rust


【解决方案1】:

您有HashMap&lt;K, V&gt;~str(拥有的字符串)作为K;因此,它想要&amp;K 对应things,即&amp;~str——对拥有的字符串的引用。但是,您将一个对静态字符串的引用传递给它(没有任何标记的字符串文字 [&amp;~ 等]、"hello",属于 &amp;'static str 类型)。

对于字符串文字,不要使用.to_str();而是在其前面加上~,即~"hello"。像这样的字符串字面量是~str 类型。对于非文字,您通常应该使用 .to_owned()&amp;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)
}

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

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

【讨论】:

  • 从 rust 1.0 开始,这不再准确
  • 是的。 HashMap API 现在更好了,因为 getcontains_key 可以采用与键类型等效的类型,这要归功于 Borrow,因此您可以只使用 h.get("foo") 而不是执行的旧 h.find(&amp;~"foo")不必要的堆分配。 play.rust-lang.org/… 是代码示例的更新,以使用当前技术。但是,我不愿意更新整个答案,因为这是一个在当前 Rust 中根本不相关的问题,这要归功于 Borrow trait。
【解决方案2】:

contains_key_equiv的声明是:

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

也就是说,它引用了 Equivalent 到 K == ~str 的内容。因此,要检查&amp;str(即Equivalent 到~str),我们需要&amp; &amp;str(对字符串切片的引用)。

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

// or

map.contains_key_equiv(& &"hello");

(请注意,它们是等价的,只是为了解决"foo" == &amp;"foo" 都是&amp;strs 的事实。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    相关资源
    最近更新 更多