At one point in time, only one variable may own a piece of data. If a given variable holds data on a stack, the data is just copied:
In case of heap data, only the pointer is copied:
Unique to Rust, the
a variable becomes invalid when the code above gets
executed. If we try to access it, it will result in a panic. Thanks to it,
during runtime Rust will not try to
free) this memory space twice,
which would be wrong.
It is called a move.
a gets moved to
Passing a value to a function also causes a move!
A function may also move ownership by returning a value. Then, the calling function’s scope owns the variable.
Sometimes we want to pass a value to a function, but also to continue to use it in the calling function. We could make the called function return the passed-in value, but that would be a weird workaround, especially if that function is supposed to return some other data as well. References come to the rescue.
Creating a reference is called borrowing. References are immutable by default. We can change that:
s variable and the
some_string reference need to use the
keyword to allow mutations of the value.
With Rust, it’s impossible to have dangling pointers. Rust will complain of such issues at compile time.
Sometimes we might need to obtain an actual value that the reference is pointing to. We can do that we the dereferencing operator:
Slice is a part of some collection. It is basically a pointer to some index of that collection and a count of elements starting from that index.
Sometimes we need to “extract” a part of a string. Instead of creating a totally new string, disconnected from the original one, we can use a String Slice.
slice contains the pointer to the first character of the slice, and the length
of the slice. Additionally, the slice has a reference to
s (?), so
be mutated while
slice is still in use.
A reference to a string is treated as a string slice.