交换 HashMap 的两个条目

hir*_*ist 5 swap hashmap rust

我有一个简单的HashMap;说HashMap<char, char>

有没有办法使用std::mem::swap(或任何其他方法)交换此哈希图中的两个元素?

当然,有一种简单的方法来获取值,get然后将它们替换为insert- 但这会触发哈希器两次(一次用于获取,然后用于插入),我正在寻找一种方法来回避第二次哈希器调用(更多内容)出于好奇心而不是为了表现)。

我尝试的是这个(在几个版本中;没有一个有效 - 正如评论中所述:entry即使我通过了编译器,也不会执行我所期望的操作):

use std::collections::HashMap;
use std::mem::swap;

let mut hash_map: HashMap<char, char> = HashMap::default();
hash_map.insert('A', 'Z');
hash_map.insert('B', 'Y');

swap(&mut hash_map.entry('A'), &mut hash_map.entry('B'));
Run Code Online (Sandbox Code Playgroud)

现在编译器抱怨(我明白为什么它应该)

error[E0499]: cannot borrow `hash_map` as mutable more than once at a time
   --> tests.rs:103:42
    |
103 |      swap(&mut hash_map.entry('A'), &mut hash_map.entry('B'));
    |      ----      --------                  ^^^^^^^^ second mutable borrow occurs here
    |      |         |
    |      |         first mutable borrow occurs here
    |      first borrow later used by call
Run Code Online (Sandbox Code Playgroud)

仅以这种方式获取两个值也会或多或少以相同的方式失败:

let mut a_val = hash_map.get_mut(&'A').expect("failed to get A value");
let mut b_val = hash_map.get_mut(&'B').expect("failed to get B value");
swap(&mut a_val, &mut b_val);
Run Code Online (Sandbox Code Playgroud)

有没有办法简单地交换 a 的两个条目HashMap

edw*_*rdw 5

我看不到任何安全的方法:

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    map.insert('A', 'Z');
    map.insert('B', 'Y');

    let a = map.get_mut(&'A').unwrap() as *mut char;
    let b = map.get_mut(&'B').unwrap() as *mut char;
    unsafe {
        std::ptr::swap(a, b);
    }

    assert_eq!(map.get(&'A'), Some(&'Y'));
    assert_eq!(map.get(&'B'), Some(&'Z'));
}
Run Code Online (Sandbox Code Playgroud)