How should I think about structures in Rust compared to C/C++?

Howdy,

I've been looking into Rust for a while, but in practicing I've noticed that while I have a pretty solid understanding of how to deal with simple structures containing primitives, dealing with larger and slightly more complex structures is still a bit of an enigma to me.

For example, I had a structure set up like below to represent a tile on a chess board:

struct Tile {
  piece: Option<ChessPiece>,
  color: ColorEnum,
}

and I was trying to make a method for the function that would swap the piece elements between two Tile structs, like below:

impl Tile {
  fn swap_pieces(&mut self, other: &mut Tile) {
    // hmm...
  }
}

I realized at this point that what I would normally do is just swap the pointers, but that isn't as simple in Rust. I found solutions online like doing:

    mem::swap(&mut self.piece, &mut other.piece)

...which seemed to work fine, but it feels like there should be some alternative.

Is there some other way to transfer ownership of members between two structures? Or rather, is there a better way to think about data structures in Rust, particularly in modifying fields?

Thanks for any insights!

1 Like

Your data structures don't have pointers to swap. If you boxed them and used mem::swap, you'd be swapping pointers with the same code. But your Option<ChessPiece> is probably smaller than a pointer.

Did you have an idea of what you would expect an alternative to look like? (It might just be that mem::swap and friends are underrepresented in the introductory material or such.)

3 Likes

I think mem::swap is perfectly good here, but this alternative using Option::take might be educational, since it shows another way of taking ownership through a mutable reference:

let tmp = self.piece.take()
self.piece = other.piece.take();
other.piece = tmp;

(You could also write this using the more general mem::take or mem::replace functions.)

Note that if ChessPiece is a Copy type, you don't even need take, and can write a swap like this:

let tmp = self.piece;
self.piece = other.piece;
other.piece = tmp;
8 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.