This is a post I wanted to write because I feel the moment I clearly understand Move Semantics I was able to
use Rust in a basic level. Obviously Rust has a steep learning curve, specially for people like me, who comes from Ruby,
so I thought this could help Rust beginners like myself to learn how to use the language.
Copy
In a few situations you want copy semantics, which means the value saved in a
variable will be copied from one point of memory to another.
For example in C you can do this:
As you can see, the assignment operator in C/C++ performs a copy of the struct from book1 to book2, so, you can freely
modify book2 without altering the values in book1, now if you want to do the same thing in Rust:
So, what happened?, the pointer address book1 was copied into book2, making book1 invalid,
transfering the ownership to book2. Other languages like Ruby does a similar thing, however book1 and book2
remains valid (without the owning part), but if you think about it, it is confusing, if you modify book2, book1
is modified as well, but that’s not the intention (at least most of the time),
because you want to copy the value, not being referenced by two variables,
at least Rust has a sane way to deal with this.
Now returning to the Rust’s example, what can we do in this case?, depending on the situation,
we can borrow the value, taking a reference of book1,
like this: let book2 = &book1; or we can implement the Clone trait like this:
Move
In another case, you want move semantics, like this one:
This error means that new_books expect a struct, not a reference,
but why is there a reference?, where does it come from?,
if you take a look at
iter method,
you can see:
The iter method takes a reference of self, in this case books, making every book item
a reference as well. What can we do? we have one option,
we can dereference book_1
changing line 28 to new_books.push(*book_1);, but now we have:
The variable book_1 was borrowed by the iter method, so we can’t move it out, but,
why does it need to move?, well,
let’s take a look at push method:
The value parameter needs to consume T, in this case book_1.
What option do we have?,
we can use into_iter,
let’s take a look at it:
It does consume self, moving books into the iterator,
the bad news is that we can’t use books anymore, so,
you need to take that into account before using the method.
I know Rust is supposed to be a C/C++ alternative, not a Ruby/Python one, however,
I feel that the lack of a garbage collector is a feature, because you are now free
of memory leaks,
besides the performance issues that Rust resolve and safeness makes it very attractive.