如何在Rust中创建和使用字符串来串联Hashmap?

Dre*_*eur 15 rust

我如何习惯性地创建一个字符串来生锈的字符串hashmap.以下是有效的,但这是正确的方法吗?我应该使用不同类型的字符串吗?

use std::collections::hashmap::HashMap;
//use std::str;
fn main() {
        let mut mymap = HashMap::new();
        mymap.insert("foo".to_string(), "bar".to_string());
        println!("{0}", mymap["foo".to_string()]);
}
Run Code Online (Sandbox Code Playgroud)

huo*_*uon 16

假设你想要的灵活性String,HashMap<String, String>是正确的.另一个选择是&str,但是这对HashMap可以使用的方式/传递方式施加了很大的限制; 但如果它有效,将一个或两个参数更改&str为更有效.这个选择应该取决于您需要什么样的所有权语义,以及字符串的动态,请参阅此答案字符串指南以获取更多信息.

BTW,HashMap<String, ...>用a 搜索String可能很昂贵:如果你还没有,它需要分配一个新的String.我们有一种形式的解决方法find_equiv,它允许您传递字符串文字(更常见的是,任何&str),而无需分配新的String:

use std::collections::HashMap;
fn main() {
    let mut mymap = HashMap::new();
    mymap.insert("foo".to_string(), "bar".to_string());
    println!("{}", mymap.find_equiv(&"foo"));
    println!("{}", mymap.find_equiv(&"not there"));
}
Run Code Online (Sandbox Code Playgroud)

游戏围栏(注意我已经离开了Option返回值,可以.unwrap()正确调用或处理丢失的密钥).

另一个稍微不同的选项(在某些情况下更常见,在其他情况下更少)是std::string::as_string函数,它允许&str&String不分配的方式查看数据(如顾名思义).它返回一个可以取消引用的对象String,例如

use std::collections::HashMap;
use std::string;

fn main() {
    let mut mymap = HashMap::new();
    mymap.insert("foo".to_string(), "bar".to_string());
    println!("{}", mymap[*string::as_string("foo")]);
}
Run Code Online (Sandbox Code Playgroud)

围栏

(有类似的std::vec::as_vec.)

  • `find_equiv()` 已被移除以支持 [`Borrow`](https://doc.rust-lang.org/std/borrow/trait.Borrow.html) 特性。`&amp;str` 和 `&amp;String` 之间的转换现在在使用 [`HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html) get/contains/remove 方法时自动完成。工作围栏 [此处](https://play.rust-lang.org/?gist=a3d3d81aa5917cad982bb8e0b5ff0ed1&amp;version=stable&amp;mode=debug&amp;edition=2015)。 (4认同)
  • 我认为它不再需要`find_equiv()` 您的Playpen示例不再编译,我在`HashMap`上看不到`find_equiv`方法. (2认同)
  • @Chad:[使用任何具有非“静态”生命周期的“str”很困难](/sf/answers/5421314951/)。如果它完全使用具有“static”生命周期的文字 str 进行键控,那就没问题。如果它是从生命周期更有限的现有“String”派生这些键,则需要确保它们至少与“HashMap”一样长,这是一个巨大的痛苦。 (2认同)

jan*_*gie 12

为未来的读者写这个答案。huon 的答案当时是正确的,但*_equiv方法不久前就被清除了。

HashMap文档提供了使用 String-String hashmap 的示例,&str可以在哪里使用。

下面的代码就可以正常工作。无需新的String分配:

use std::collections::HashMap;

fn main() {
    let mut mymap = HashMap::new();
    mymap.insert("foo".to_string(), "bar".to_string());
    println!("{0}", mymap["foo"]);
    println!("{0}", mymap.get("foo").unwrap());
}
Run Code Online (Sandbox Code Playgroud)