Assuming you would like the flexibility of String
, HashMap<String, String>
is correct. The other choice is &str
, but that imposes significant restrictions on how the HashMap
can be used/where it can be passed around; but if it it works, changing one or both parameter to &str
will be more efficient. This choice should be dictated by what sort of ownership semantics you need, and how dynamic the strings are, see this answer and the strings guide for more.
BTW, searching a HashMap<String, ...>
with a String
can be expensive: if you don't already have one, it requires allocating a new String
. We have a work around in the form of find_equiv
, which allows you to pass a string literal (and, more generally, any &str
) without allocating a new 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"));
}
playpen (note I've left the Option
in the return value, one could call .unwrap()
or handle a missing key properly).
Another slightly different option (more general in some circumstances, less in others), is the std::string::as_string
function, which allows viewing the data in &str
as if it were a &String
, without allocating (as the name suggests). It returns an object that can be dereferenced to a String
, e.g.
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")]);
}
playpen
(There is a similar std::vec::as_vec
.)