Below is a graphical depiction of moving, copying, and borrowing in the Rust language. Most of these concepts are fairly specific to Rust and are therefore a common stumbling block for many learners.

To avoid clutter in the graphics, I have tried to keep the text to a minimum. It isn’t meant to be a replacement for the various tutorials out there but more of a different perspective for programmers who prefer to grok concepts visually. If you are learning Rust and find these graphics helpful, I would recommend annotating your own code with such diagrams to help solidify the concepts :)

You can zoom in by clicking the image. You can also get it as an SVG or PDF.

The upper two figures depict the two main kinds of semantics for data that you own: either move semantics or copy semantics.

The picture on move semantics (⤳) looks almost too simple. There is no deception here: move semantics are strange only because most languages allow variables to be used as many times as the programmers please. This stands in contrast to much of the real world: I can’t just give someone my pen and still use it for writing! In Rust, any variable whose type does not implement the Copy trait has move semantics and would behave as shown.

(⤳) looks almost too simple. There is no deception here: move semantics are strange only because most languages allow variables to be used as many times as the programmers please. This stands in contrast to much of the real world: I can’t just give someone my pen and still use it for writing! In Rust, any variable whose type does not implement the trait has move semantics and would behave as shown. Copy semantics (⎘) are reserved for types that do implement the Copy trait. In this case, every use of the object would result in a copy, as shown by the bifurcation.

The central two figures depict the two ways in which you can borrow an object you own, and what each one offers.

For mutable borrowing , I used a lock symbol (🔒) to signify that the original object is effectively locked for the duration of the borrow, rendering it unusable.

, I used a lock symbol (🔒) to signify that the original object is effectively locked for the duration of the borrow, rendering it unusable. In contrast, for non-mutable borrowing I used a snowflake symbol (❄) to indicate that the original object is only frozen: you can still take more non-mutable references, but you cannot move or take mutable references of it.

In both figures, ’ ρ is a name I have chosen for the lifetime of the references. I used a Greek letter on purpose because there is no syntax for concrete lifetimes in Rust, currently.