Hands-on Rust: clone_dirty cloning HashSet

Title: Hands-On Rust (Chapter 10)

This has been bugging me a bit since coding it, so I tried the change and it seems to work.

Isn’t it a bit expensive to clone a HashSet that you intend to immediately replace?

I tried the following change to clone_dirty(&self) -> Self

    pub fn clone_dirty(&self) -> Self {
        // let mut cloned = self.clone(); // TODO: isn't this expensive??
        // cloned.is_dirty = true;
        // cloned
        Self {
            visible_tiles: HashSet::new(),
            radius: self.radius,
            is_dirty: true,
        }
    }

Game play seems to be working fine so far. I’m assuming that creating a new HashSet is less expensive than closing a populated HashSet. That also raised the question for me as to whether visible_tiles should be Option instead and the None would serve the same purpose as is_dirty. Maybe I’ll see that this is a bad idea as I progress…

I tried the Option (and remove (is_dirty)) change. It originally made a few checks more verbose/painful. Then, because of the repetition, I added

    pub fn is_visible(&self, pt: &Point) -> bool {
        match &self.visible_tiles {
            Some(vt) => vt.contains(pt),
            None => false,
        }
    }

to the FieldOfView struct impl, and used that. All seems to be working fine. I suppose that the risk is that I’ll get a false on is visible when I would, previously have gotten a true when querying the “dirty” HashSet. I suspect, though, that using the results of querying a dirty HashSet is more likely to be a bug.

That’s a good point; clone can be expensive (it’s remarkable how well LLVM optimizes it out, especially on release builds). There’s a bit of compiler magic that notices that it’s basically a set of memcpy calls under the hood, and elides them. I like your approach better, though - it’s dangerous to rely on the compiler noticing an optimization when you can tell it what you want.

Adding an is_visible method is also a great idea. I’ll see if I can refactor the book code a little.

I’ll try and merge this into the next beta. Thank you!