使用对另一个哈希图的引用克隆一个哈希图

abh*_*jat 2 reference hashmap rust

我有一个哈希映射的引用(data在下面的代码中),我想将其克隆到一个新的、拥有的哈希映射中。克隆参考给了我一个新的参考,这不是我需要的。

我还尝试对data引用进行迭代 + 映射,并单独克隆键和值对,然后进行收集,但这也不起作用。这是一个最小的工作示例:

use core::cell::Cell;
use std::collections::HashMap;
use std::collections::HashSet;
use std::rc::Rc;

struct Dummy<K, V> {
    dirty: Rc<Cell<bool>>,
    data: Cell<Option<HashMap<K, HashSet<V>>>>,
}

impl<K, V> Dummy<K, V> {
    fn persist(&self, prefix: &str, data: &HashMap<K, HashSet<V>>) {
        self.dirty.set(true);
        self.data.set(Some(data.clone()));
    }
}
Run Code Online (Sandbox Code Playgroud)

这给出了以下错误:

error[E0308]: mismatched types
  --> src/lib.rs:14:28
   |
14 |         self.data.set(Some(data.clone()));
   |                            ^^^^^^^^^^^^ expected struct `std::collections::HashMap`, found reference
   |
   = note: expected type `std::collections::HashMap<K, std::collections::HashSet<V>>`
              found type `&std::collections::HashMap<K, std::collections::HashSet<V>>`
Run Code Online (Sandbox Code Playgroud)

固定链接到操场

这段代码的目的是通过Dummystruct观察hashmap的内容,用于单元测试。

我猜这个问题是因为给定泛型类型没有办法确定如何深度克隆键和值对象?

有没有办法在给定对现有哈希图的引用的情况下创建新的哈希图?

use*_*968 7

正如评论所暗示的那样,这是 Rust 如何通过引用 / autoderef 查找方法的一个有点不幸的交互:

Cloneon的实现也HashMap需要键和值(以及哈希器)Clone。这是有道理的,因为我们只能克隆它,HashMap如果我们可以克隆它的内容。如果其中任何一个不执行CloneHashMap则不执行Clone

impl<K, V>Clone. 那么为什么调用data.clone()甚至工作呢?那是因为在任何引用上都有一个实现Clone,它为您提供了引用的副本。

由于您impl<K, V>Kor上没有界限V,编译器只会发现Clone原始&-type上的 -implementation是适用的。如果您需要K: Clone, V: Clone,则应用HashMap自己的Clone-impl(默认情况下S已经Clone是)。

看这个例子:

// This returns a cloned HashMap
// because Rust uses the Clone-implementation on HashMap
fn do_clone<K: Clone, V: Clone>(data: &HashMap<K,V>) -> HashMap<K, V> {
    data.clone()
}

// There is no viable Clone-implementation on the HashMap
// because K & V are not Clone. But there is an implementation
// on the primitive reference type.
fn do_clone_ref<K, V>(data: &HashMap<K,V>) -> &HashMap<K, V> {
    data.clone()
}
Run Code Online (Sandbox Code Playgroud)