Beginner: How to reference attributes after move

#1

Why am I able to use attributes of rect1 after the move?
How can I reference rect1 to get the value of id?

I know I can move line 24 below the loops to avoid moving, but I’m confused why some references to the moved value work, and some don’t.

use std::collections::{HashSet, HashMap};

struct Rect {
    id: u32,
    x: u32,
    y: u32,
    width: u32,
    height: u32
}

fn main() {

  let mut registry: HashMap<u32, Rect> = HashMap::new();
  let mut grid: HashMap<(u32,u32), HashSet<u32>> = HashMap::new();

  let rect1 = Rect {
      id: 1,
      x: 0,
      y: 0,
      width: 10,
      height: 4
  };
  
  registry.insert(rect1.id, rect1); // move occurs here
  
  for x in rect1.x..(rect1.x + rect1.width) {   // after the move, why am i able to use attributes here?
      for y in rect1.y..(rect1.y + rect1.width) { // and here
          let coordinate = (x, y);
          let set = grid.entry(coordinate).or_insert(HashSet::new());
          set.insert(rect1.id);     // rect1 has moved already, how should i reference rect1 to get id?
      }
  }
}

(Playground)

0 Likes

#2

You playground code doesn’t compile. Maybe you meant to derive Clone and Copy for Rect. In that case, it is because you made Rect Copy, whenever it tries to move it will do a bitwise copy of Rect so you can access it afterwards.

Because Rect is just data, it is reasonable to implement Clone and Copy

0 Likes

#3

Hi, the compiler is not complaining about line 26 and 27 only because it’s already complaining about line 30, if you comment it out it will complain about line 27.
To make it work just move line 24 below the loop like you said.

0 Likes

#4

You’re right, thanks leudz - I’m glad you pointed that out. I found that confusing.

0 Likes