【问题标题】:Cloning a hashmap using a reference to another hashmap使用对另一个 hashmap 的引用克隆一个 hashmap
【发布时间】:2020-04-09 21:25:49
【问题描述】:

我有一个哈希图的引用(下面代码中的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()));
    }
}

这给出了以下错误:

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>>`

(Permalink to the playground)

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

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

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

【问题讨论】:

  • 如果你使用impl&lt;K: Clone, V: Clone&gt; 会怎样?

标签: rust reference hashmap


【解决方案1】:

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

The implementation of Clone on HashMap 要求键和值(以及哈希)也为Clone。这是有道理的,因为我们只能克隆HashMap,如果我们可以克隆它的内容。如果其中任何一个没有实现Clone,则HashMap 不会实现Clone

您的impl&lt;K, V&gt;Clone 没有限制。那么为什么对data.clone() 的调用甚至可以正常工作呢?那是因为有一个implementation of Clone on any reference,它会为您提供参考的副本。

由于您的impl&lt;K, V&gt;KV 上没有界限,因此编译器只会在原语&amp;-type 上找到Clone-实现适用。如果您需要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()
}

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 2020-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多