我在rust的推荐信上遇到了点麻烦。我有以下不能编译的代码:
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));
}
我得到的编译错误是:
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
果然,如果我更改了行:
assert_eq!(map.get(&0), Some(&0));
to assert_eq!(map.get(&0), Some(&&0));
(双与号)代码编译
问题:
map.insert(&0, &0)
将指向两个整数文字的指针插入到映射中。我甚至不确定这是如何实现的,因为我没有在任何地方使用变量。我怎么能引用一个文字呢?我原以为编译器会让我这样做:let a = 0;
let b = 0
map.insert(&a, &b);
换句话说,&0
到底是什么意思呢?它是否为文字分配内存并返回对它的引用?如果是这样,那么我假设不会有两个&0
指向相同的内存,这是正确的吗?
Some(&&0)
而不只是Some(&0)
?&&0
到底是什么意思?我知道**ptr
意味着两次取消对变量的引用,以获得底层的值。但我不能完全想象相反的情况-你怎么能两次“引用”一个整型文字呢?发布于 2019-03-04 20:39:12
如果你看看insert
和get
的签名,你就会意识到他们处理事情的方式是不同的。
从HashMap<K, V>
开始
fn insert(&mut self, k: K, v: V) -> Option<V>
.fn get(&self, k: &K) -> Option<&V>
(simplified).如您所见,insert
获取所有权,处理值,而get
获取并返回引用。
因此,如果你insert
&1
,你get
Some(&&1)
back:再多一层引用。
那么,问题是为什么.get(&0)
没有错误:它不是缺少一个引用级别吗?
好吧,我欺骗并简化了get的签名,the exact signature是:
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> where
K: Borrow<Q>,
Q: Hash + Eq,
事实证明,&T
实现了Borrow<T>
,因此您可以使用&K
为&&K
调用get。
如果您设法让编译器为您提供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
和V
计算出的类型,实际上它将是&{integer}
,因为您将&0
传递给insert
,它通过值获取键和值。
至于生命周期的问题:
'static
生存期之后执行,就像"Hello"
具有&'static str
类型一样。编译器会自动在程序中的某处为文字保留内存,并在必要时“借用”它们。这意味着创建一个对文字整数的引用是非常好的:&0i32
具有&'static i32
类型。
https://stackoverflow.com/questions/54982977
复制相似问题