gpt4 book ai didi

rust - 为什么从 HashMap 获取值时需要双符号?

转载 作者:行者123 更新时间:2023-11-29 08:12:04 24 4
gpt4 key购买 nike

我在处理 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));assert_eq!(map.get(&0), Some(&&0)); (双符号)代码编译

问题:

  1. map.insert(&0, &0) 将指向两个整数文字的指针插入到映射中。我不确定这怎么可能,因为我没有在任何地方使用过变量。我怎样才能引用文字?我期待编译器让我这样做:
let a = 0;
let b = 0
map.insert(&a, &b);

换句话说,&0 到底是什么意思?它是否为文字分配内存并返回对它的引用?如果是这样,那么我假设没有两个 &0 会指向同一内存是否正确?

  1. 为什么我必须做 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) 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 调用 get对于 &&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 计算出的类型和 V , 实际上它将是 &{integer} ,因为你通过了 &0insert它按值获取键和值。


关于生命周期的问题:

  1. 并非所有检查都一次性完成。特别是,借用/生命周期检查通常类型检查之后进行。
  2. 文字具有 'static一生,就像"Hello"&'static str类型。

编译器自动在程序的某处为文字保留内存,并在必要时“借用”它们。这意味着创建对文字整数的引用完全没问题:&0i32类型为 &'static i32 .

关于rust - 为什么从 HashMap 获取值时需要双符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54982977/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com