我在参考锈方面遇到了麻烦。我有以下无法编译的代码:
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert(&0, &0);
map.insert(&1, &1);
assert_eq!(map.get(&0), Some(&0));
}
Run Code Online (Sandbox Code Playgroud)
我得到的编译错误是:
error[E0308]: mismatched types
--> rust_doubt.rs:9:5
|
9 | assert_eq!(map.get(&0), Some(&0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &{integer}, found integral variable
|
= note: expected type `std::option::Option<&&{integer}>`
found type `std::option::Option<&{integer}>`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
果然,如果我改变这一行:
assert_eq!(map.get(&0), Some(&0));
到assert_eq!(map.get(&0), Some(&&0));
(双号)的代码编译
map.insert(&0, &0)
将指向两个整数文字的指针插入映射。我不确定这怎么可能,因为我没有在任何地方使用变量。如何引用文字?我期望编译器使我做到这一点:let a = 0;
let b = 0
map.insert(&a, &b);
Run Code Online (Sandbox Code Playgroud)
换句话说,这&0
甚至意味着什么?它是否为文字分配内存并返回对其的引用?如果是这样,那么我假设没有两个&0
s指向相同的内存是正确的吗?
Some(&&0)
而不是仅仅做Some(&0)
?&&0
甚至是什么意思?我理解这**ptr
意味着两次对变量进行解引用以获取基础值。但是我无法完全想象相反的情况-您如何两次“引用”整数文字?如果你看的签名insert
和get
你会发现,他们处理不同的事情。
从开始HashMap<K, V>
:
fn insert(&mut self, k: K, v: V) -> Option<V>
。fn get(&self, k: &K) -> Option<&V>
(简体)。如您所见,insert
需要所有权,处理值,而get
需要并返回引用。
因此,如果您insert
&1
愿意的话,您将get
Some(&&1)
返回:参考的另一层。
那么,问题是:为什么没有错误.get(&0)
:它是否缺乏参考水平?
好吧,我欺骗并简化了get的签名,确切的签名是:
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> where
K: Borrow<Q>,
Q: Hash + Eq,
Run Code Online (Sandbox Code Playgroud)
事实证明,它是&T
实现的Borrow<T>
,因此您可以调用get with &K
for &&K
。
如果您设法使编译器为您提供的类型,HashMap
则要容易一些:
assert_eq!(map, ());
Run Code Online (Sandbox Code Playgroud)
结果是:
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)
Run Code Online (Sandbox Code Playgroud)
它显示了编译器为K
和找出的类型V
,实际上将为&{integer}
,因为您传递&0
给的insert
是按值和键值。
至于寿命问题:
'static
寿命的,就像"Hello"
有&'static str
型。编译器会自动在程序中的某个位置保留用于文字的内存,并将在必要时“借用”它们。这意味着创建对文字整数的引用非常好:&0i32
具有type &'static i32
。
归档时间: |
|
查看次数: |
180 次 |
最近记录: |