forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#24466 - steveklabnik:more_more_more, r=alex…
…crichton Link to the big chapter for now, and add move semantics.
- Loading branch information
Showing
3 changed files
with
105 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
% Lifetimes | ||
|
||
Coming soon! | ||
Coming Soon! Until then, check out the [ownership](ownership.html) chapter. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,105 @@ | ||
% Move Semantics | ||
|
||
Coming Soon | ||
An important aspect of [ownership][ownership] is ‘move semantics’. Move | ||
semantics control how and when ownership is transferred between bindings. | ||
|
||
[ownership]: ownership.html | ||
|
||
For example, consider a type like `Vec<T>`, which owns its contents: | ||
|
||
```rust | ||
let v = vec![1, 2, 3]; | ||
``` | ||
|
||
I can assign this vector to another binding: | ||
|
||
```rust | ||
let v = vec![1, 2, 3]; | ||
|
||
let v2 = v; | ||
``` | ||
|
||
But, if we try to use `v` afterwards, we get an error: | ||
|
||
```rust,ignore | ||
let v = vec![1, 2, 3]; | ||
let v2 = v; | ||
println!("v[0] is: {}", v[0]); | ||
``` | ||
|
||
It looks like this: | ||
|
||
```text | ||
error: use of moved value: `v` | ||
println!("v[0] is: {}", v[0]); | ||
^ | ||
``` | ||
|
||
A similar thing happens if we define a function which takes ownership, and | ||
try to use something after we’ve passed it as an argument: | ||
|
||
```rust | ||
fn take(v: Vec<i32>) { | ||
// what happens here isn’t important. | ||
} | ||
|
||
let v = vec![1, 2, 3]; | ||
|
||
take(v); | ||
|
||
println!("v[0] is: {}", v[0]); | ||
``` | ||
|
||
Same error: “use of moved value.” When we transfer ownership to something else, | ||
we say that we’ve ‘moved’ the thing we refer to. You don’t need some sort of | ||
special annotation here, it’s the default thing that Rust does. | ||
|
||
# The details | ||
|
||
The reason that we cannot use a binding after we’ve moved it is subtle, but | ||
important. When we write code like this: | ||
|
||
```rust | ||
let v = vec![1, 2, 3]; | ||
|
||
let v2 = v; | ||
``` | ||
|
||
The first line creates some data for the vector on the stack, `v`. The vector’s | ||
data, however, is stored on the heap, and so it contains a pointer to that | ||
data. When we move `v` to `v2`, it creates a copy of that data, for `v2`. Which | ||
would mean two pointers to the contents of the vector on the heap. That would | ||
be a problem: it would violate Rust’s safety guarantees by introducing a data | ||
race. Therefore, Rust forbids using `v` after we’ve done the move. | ||
|
||
It’s also important to note that optimizations may remove the actual copy of | ||
the bytes, depending on circumstances. So it may not be as inefficient as it | ||
initially seems. | ||
|
||
# `Copy` types | ||
|
||
We’ve established that when ownership is transferred to another binding, you | ||
cannot use the original binding. However, there’s a [trait][traits] that changes this | ||
behavior, and it’s called `Copy`. We haven’t discussed traits yet, but for now, | ||
you can think of them as an annotation to a particular type that adds extra | ||
behavior. For example: | ||
|
||
```rust | ||
let v = 1; | ||
|
||
let v2 = v; | ||
|
||
println!("v is: {}", v); | ||
``` | ||
|
||
In this case, `v` is an `i32`, which implements the `Copy` trait. This means | ||
that, just like a move, when we assign `v` to `v2`, a copy of the data is made. | ||
But, unlike a move, we can still use `v` afterward. This is because an `i32` | ||
has no pointers to data somewhere else, copying it is a full copy. | ||
|
||
We will discuss how to make your own types `Copy` in the [traits][traits] | ||
section. | ||
|
||
[traits]: traits.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
% References and Borrowing | ||
|
||
Coming Soon! | ||
Coming Soon! Until then, check out the [ownership](ownership.html) chapter. |