【问题标题】:Is there any way to clone a reference type into an owned type? [duplicate]有没有办法将引用类型克隆为拥有类型? [复制]
【发布时间】:2019-12-20 14:22:39
【问题描述】:

我有一个方法,我想返回一个元素的拥有副本。如果需要,我可以证明我为什么想要这个。

这是一个最小的可重现示例:(playground)

use std::collections::HashMap;

struct AsciiDisplayPixel {
    value: char,
    color: u32,
}

struct PieceToPixelMapper {
    map: HashMap<usize, AsciiDisplayPixel>,
}

impl PieceToPixelMapper {
    pub fn map(&self, index: usize) -> Option<AsciiDisplayPixel> {
        let pixel = self.map.get(&index);
        let pixel = match pixel {
            None => return None,
            Some(x) => x,
        };

        return Some(pixel.clone());
    }
}

fn main() {
    println!("Hello World");
}

编译失败

error[E0308]: mismatched types
  --> src/main.rs:20:21
   |
20 |         return Some(pixel.clone());
   |                     ^^^^^^^^^^^^^ expected struct `AsciiDisplayPixel`, found reference
   |
   = note: expected type `AsciiDisplayPixel`
              found type `&AsciiDisplayPixel`

我不确定为什么会这样。根据documentation on clone,它看起来像clone 的结果类型是无论父级是什么,所以如果你克隆一个引用,你仍然会得到一个引用,我想如果没问题,但我不知道我是如何克隆到拥有的数据。 to_owned 似乎有完全相同的问题并给出相同的错误消息。

【问题讨论】:

    标签: reference rust clone ownership


    【解决方案1】:

    AsciiDisplayPixel 需要实现 Clone 以便您能够克隆(CopyDebug 和其他可能也有意义):

    #[derive(Clone)]
    struct AsciiDisplayPixel {
        value: char,
        color: u32,
    }
    

    (updated playground)

    此时实现可以简化为:

    pub fn map(&self, index: usize) -> Option<AsciiDisplayPixel> {
        self.map.get(&index).cloned()
    }
    

    【讨论】:

    • map 实际上是一个HashMap&lt;usize, AsciiDisplayPixel&gt;。所以pixel&amp;AsciiDisplayPixel。我已经编辑了我的问题以包含一个完整的可重现示例。
    • @TechnoSam:问题在于AsciiDisplayPixel 不是Clone
    • 非常感谢,事后看来这很明显!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 2010-11-23
    • 1970-01-01
    • 2014-01-09
    • 2023-01-03
    相关资源
    最近更新 更多