[英]How to use a Box<String> as a lookup key for a hashmap with &str keys?
My hashmap keys are expected to be of type &str
, in particular &'static str
, and I've received an owned Box<String>
.我的 hashmap 键应该是
&str
类型,特别是&'static str
,我收到了一个拥有的Box<String>
。
How do I search my string against my hashmap?如何根据我的哈希图搜索我的字符串?
use std::collections::HashMap;
fn main() {
let mut map: HashMap<&str, u32> = HashMap::new();
let static_string = "a";
map.insert(static_string, 5);
let owned_boxed_string = Box::new(String::from("a"));
map.get(owned_boxed_string); // mismatched type (ok)
map.get(*owned_boxed_string); // mismatched type (ok)
map.get(&*owned_boxed_string); // trait bound not satisfied (?)
}
Let's look at the definition of HashMap::get()
:我们来看看
HashMap::get()
的定义:
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> where
K: Borrow<Q>,
Q: Hash + Eq,
In your code, K
is &'static str
and Q
is deduced from each of the calls to get
.在您的代码中,
K
是&'static str
并且Q
是从对get
每次调用中推导出来的。 In plain English, get()
takes a reference to a type Q
such that &'static str
implements Borrow<Q>
.在简单的英语中,
get()
引用类型Q
使得&'static str
实现Borrow<Q>
。
The rationale is that usually you will store keys of type String
or the like, and you will search using values of type &str
.基本原理是通常您将存储
String
或类似类型的键,并且您将使用&str
类型的值进行搜索。 And naturally String
implements Borrow<str>
so you can do that.自然
String
实现Borrow<str>
所以你可以做到这一点。
In your case, your key is not String
but &'static str
... Take a look at the documentation for Borrow
and look for what kind of Borrow<Q>
is implemented by &'static str
.在您的情况下,您的键不是
String
而是&'static str
... 查看Borrow
的文档并查找&'static str
实现的Borrow<Q>
类型。 I can only see these two blanket implementations:我只能看到这两个全面的实现:
impl<'_, T: ?Sized> Borrow<T> for &'_ T
impl<T: ?Sized> Borrow<T> for T
The first one states that if your map keys are references to some type &K
you can call get(k: &K)
.第一个指出,如果您的地图键是对某种类型
&K
引用,您可以调用get(k: &K)
。 The second one says that if your key is K
you can call get(k: &K)
.第二个说如果你的密钥是
K
你可以调用get(k: &K)
。
So for your particular case of &'static str
they are realized as:因此,对于
&'static str
特殊情况,它们被实现为:
impl Borrow<str> for &'static str
impl Borrow<&'static str> for &'static str
From that you can deduce that your function is either get(k: &str)
or get(k: &&str)
.从中您可以推断出您的函数是
get(k: &str)
或get(k: &&str)
。 Here the easiest choice is the first one.这里最简单的选择是第一个。
Now, you may think that your last line ( map.get(&*owned_boxed_string);
) should work, because that value is of type &str
, but it actually is not, it is of type &String
.现在,您可能认为您的最后一行(
map.get(&*owned_boxed_string);
)应该可以工作,因为该值的类型为&str
,但实际上不是,它的类型为&String
。 If HashMap::get()
received a &str
it would compile fine, but taking a Borrow<Q>
, the compiler gets all confused and fails.如果
HashMap::get()
收到一个&str
它会编译得很好,但是如果使用Borrow<Q>
,编译器就会感到困惑并失败。
TL; TL; DR;
博士; : Add a type cast or a temporary typed variable:
:添加类型转换或临时类型变量:
map.get(&*owned_boxed_string as &str); //ok
map.get(&owned_boxed_string as &str); //also ok
let s: &str = &*owned_boxed_string;
map.get(s);
let s: &str = &owned_boxed_string;
map.get(s);
Although an easier solution (thanks to @harmic for the comment below) is to use String::as_str()
that will take care of as many derefs as required and just return the necessary &str
:尽管更简单的解决方案(感谢@harmic 提供下面的评论)是使用
String::as_str()
,它将根据需要处理尽可能多的 deref 并只返回必要的&str
:
map.get(owned_boxed_string.as_str());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.