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

2024-02-21

我在 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));(双&符号)代码编译

问题:

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

换句话说,什么是&0甚至意味着?它是否为文字分配内存并返回对其的引用?如果是这样,那么我假设没有两个是正确的&0s 会指向相同的内存吗?

  1. 为什么我必须做Some(&&0)而不是仅仅Some(&0)?什么是&&0甚至意味着?我明白那个**ptr意味着取消引用一个变量两次以获得底层值。但我无法完全想象相反的情况 - 你怎么能“引用”一个整数文字两次?

如果你看一下签名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它按值获取键和值。


至于寿命问题:

  1. 并非所有检查都是一次性完成的。特别是,通常会进行借用/终身检查after类型检查。
  2. 文字有'static一生,就像"Hello"&'static str type.

编译器会自动在程序中的某个位置为文字保留内存,并根据需要“借用”它们。这意味着创建对文字整数的引用是完全可以的:&0i32有类型&'static i32.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 HashMap 获取值时为什么需要双 & 符号? 的相关文章

随机推荐

  • 如何将对象转换为字符串以便与 ActiveRecord 查询一起使用?

    我有一个User 其中有一个String email属性 但是 当我在应用程序中处理电子邮件时 我发现最好先将其转换为 非持久 Email对象 就像这样 class User lt ActiveRecord Base def email E
  • Cron:每 1 秒运行一次 cron?

    如何让 cron 每 1 秒运行一次 默认只有分钟选项 让 cron 第一次开始这项工作 将程序置于无限循环中 每次循环结束时 sleep 1 秒 像这样 在C中 int main int argc char argv while 1 do
  • 如何在 Android 中启用 Google Chrome 的“扫描新卡”选项?

    Google Chrome 具有扫描信用卡以在付款期间填充字段的功能 该功能适用 于 Android Chrome 不适用于 Android 的所有版本和设备 我已附上屏幕截图 It shows on other websites but
  • 在 C++11 智能指针中存储 std::thread

    In C 11 多于有什么优点或缺点当存储一个std thread直接作为班级成员 如下所示 std thread my thread 与存储相反std shared ptr or std unique ptr像这样的线程 std shar
  • 如何从 Google 版本地图中拖动的标记获取格式化地址

    我制作了一个谷歌地图 可以让你在文本字段中输入地址 然后 它会将您导航到您在文本字段中输入的地址 并留下一个可拖动的标记 拖动时会显示纬度和经度以及地理位置地址 我不想显示上述地址 而是希望当您拖动标记时在底角显示标记的地址 而不是从文本字
  • 纯 CSS 中基于复选框隐藏表格行

    对于那些关心的人来说 有一些背景故事 不久前我偶然发现了这个 https medium com front end hacking how it feels to learn javascript in 2017 a934b801fbe h
  • Windows 上的 Python str 与 unicode,Python 2.7,为什么 'á' 变成 '\xa0'

    背景 我使用的是 Windows 机器 我知道不再支持 Python 2 但我仍在学习 Python 2 7 16 我还有Python 3 7 1 我知道Python 3 unicode被重命名为str https stackoverflo
  • EntityManagerFactory 已关闭,Hibernate

    我最近创建了一个 Web 服务 它使用 Java 中的静态方法从数据库中获取项目列表 Web 服务运行良好 并将 JSON 返回给调用者 然而 它只能工作一次 如果您尝试刷新或提出新请求 我会收到一个EntityManagerFactory
  • J:牛顿法的隐性副词

    我发现在 addons math misc brent ijs 布伦特方法作为副词的实现 我也想构建牛顿法作为副词 但这比构建默认动词要困难得多 这是牛顿迭代的显式版本 newton i 1 u u d 1 有了这样的用法 2 o newt
  • 在哪里可以找到 javascript 本机函数源代码? [复制]

    这个问题在这里已经有答案了 哪里可以找到原生js函数的源码 比如我想看一下eval 功能 Chrome 和 Firefox 都是开源的 您可以在这些产品的源代码中查看 javascript 引擎任何部分的实现 其他浏览器有自己的实现 例如
  • Android 上的 Cordova 全屏黑条

    我的 android cordova 应用程序在屏幕顶部和底部出现黑色水平条 我尝试将全屏插件和标签添加到 config xml 但它不会消失 https i stack imgur com esFEL png https i stack
  • 从 mongodb 结果 java 中删除 _id

    我的代码是 DBCollection collection db getCollection volume DBCursor cursor collection find DBObject resultElement cursor next
  • Oracle 数据库查询在第二次运行时抛出错误

    我有一个 VBA 代码 我在其中调用 oracle 使用 ODBC 检索数据两次 第一次数据检索没问题 但第二次却说 RunTime Error 2147467259 80004005 Unspecified error 我的代码如下 注意
  • 如何禁用 NSDocument 的窗口标题弹出窗口

    我有一个基于 NSDocument 的应用程序 启用了自动保存 I d like to prevent this popup from showing 我尝试从 NSWindow 的 title representedFilename 和
  • 如何在访问 laravel 环境和类时在命令行上运行 php 脚本

    我在 Web 服务器上有一个 laravel 3 环境 但我想在命令行上运行 php 脚本 我想访问 laravel 环境中的任何 php 脚本 例如控制器 模型或视图文件 访问的相同类和方法 我怎样才能做到这一点 我强烈建议您将 PHP
  • Python - SQLite JSON1 加载扩展

    我想在 Python 中使用 SQLite 的 json1 扩展 根据官方文档 http sqlite org json1 html 它应该是一个可加载的扩展 我从以下位置获取了 json1 c 文件source http sqlite o
  • 在Python中解压文件

    我通读了zipfile文档 https docs python org 3 library zipfile html 但不明白如何unzip一个文件 仅介绍如何压缩文件 如何将 zip 文件的所有内容解压缩到同一目录中 import zip
  • Haskell:在更新函数中引用先前更新的列表元素

    假设我有以下定义 data Book Book id Int title String type Shelf Book 假设我有一个假设的功能 upd用于更新 updShelf Shelf gt Shelf updShelf all boo
  • OSGI环境中单例的迁移解决方案

    我正在 Java EE 环境中工作 其中每个应用程序都位于其自己的 war 文件中 在每个应用程序 war 文件的 WEB INF lib 中 有一个由所有应用程序共享的公共 jar 这个公共 jar 包含几个可以从代码中的许多点访问的单例
  • 从 HashMap 获取值时为什么需要双 & 符号?

    我在 Rust 中的引用方面遇到了一些麻烦 我有以下无法编译的代码 use std collections HashMap fn main let mut map HashMap new map insert 0 0 map insert