如果你看一下签名insert
and get
你会意识到他们处理事情的方式不同。
从一个开始HashMap<K, V>
:
-
fn insert(&mut self, k: K, v: V) -> Option<V>
.
-
fn get(&self, k: &K) -> Option<&V>
(简化)。
如你看到的,insert
takes 所有权, 处理values, while get
接受并返回一个参考.
因此,如果您insert
&1
, you get
Some(&&1)
背面:多一层参考。
那么问题是为什么没有错误.get(&0)
: 是不是缺乏参考性?
好吧,我作弊并简化了 get 的签名,确切的签名 https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.get is:
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> where
K: Borrow<Q>,
Q: Hash + Eq,
事实证明&T
实施Borrow<T>
,这样你就可以调用 get 了&K
for &&K
.
如果你设法让编译器为你提供类型HashMap
,这更容易一些:
assert_eq!(map, ());
结果是:
error[E0308]: mismatched types
--> src/main.rs:9:5
|
9 | assert_eq!(map, ());
| ^^^^^^^^^^^^^^^^^^^^ expected struct `std::collections::HashMap`, found ()
|
= note: expected type `std::collections::HashMap<&{integer}, &{integer}>`
found type `()`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
它显示了编译器计算出的类型K
and V
,而且确实会是&{integer}
,既然你通过了&0
to insert
它按值获取键和值。
至于寿命问题:
- 并非所有检查都是一次性完成的。特别是,通常会进行借用/终身检查after类型检查。
- 文字有
'static
一生,就像"Hello"
有&'static str
type.
编译器会自动在程序中的某个位置为文字保留内存,并根据需要“借用”它们。这意味着创建对文字整数的引用是完全可以的:&0i32
有类型&'static i32
.