1

I have a method that I want to return an owned copy of an element. I can justify why I want this if needed.

Here is a minimal reproducible example: (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");
}

This fails to compile with

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`

I'm not sure why this is the case. According to the documentation on clone, it looks like the resulting type of clone be whatever the parent was, so if you clone a reference, you still get a reference, which I guess if fine, but then I have no clue how I clone to owned data. to_owned seems to have the exact same problem and gives the same error message.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
TechnoSam
  • 578
  • 1
  • 8
  • 23

1 Answers1

4

AsciiDisplayPixel needs to implement Clone for you to be able to clone (Copy, Debug, and others probably make sense too):

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

(updated playground)

at which point the implementation can be simplified to:

pub fn map(&self, index: usize) -> Option<AsciiDisplayPixel> {
    self.map.get(&index).cloned()
}
Ry-
  • 218,210
  • 55
  • 464
  • 476