Skip to content

Commit d7cfc34

Browse files
committed
auto merge of rust-lang#16119 : steveklabnik/rust/guide_pointers, r=brson
This is the next section of the guide, and it's on pointers. It's not done yet, as I need to write the section on ownership and borrowing, but I figured I'd share the rest now, to get feedback on the rest of it while I take some time to get that right.
2 parents 292caef + a74197e commit d7cfc34

File tree

1 file changed

+255
-7
lines changed

1 file changed

+255
-7
lines changed

src/doc/guide.md

+255-7
Original file line numberDiff line numberDiff line change
@@ -3387,23 +3387,271 @@ out.
33873387

33883388
# Pointers
33893389

3390+
In systems programming, pointers are an incredibly important topic. Rust has a
3391+
very rich set of pointers, and they operate differently than in many other
3392+
languages. They are important enough that we have a specific [Pointer
3393+
Guide](/guide-pointers.html) that goes into pointers in much detail. In fact,
3394+
while you're currently reading this guide, which covers the language in broad
3395+
overview, there are a number of other guides that put a specific topic under a
3396+
microscope. You can find the list of guides on the [documentation index
3397+
page](/index.html#guides).
3398+
3399+
In this section, we'll assume that you're familiar with pointers as a general
3400+
concept. If you aren't, please read the [introduction to
3401+
pointers](/guide-pointers.html#an-introduction) section of the Pointer Guide,
3402+
and then come back here. We'll wait.
3403+
3404+
Got the gist? Great. Let's talk about pointers in Rust.
3405+
3406+
## References
3407+
3408+
The most primitive form of pointer in Rust is called a **reference**.
3409+
References are created using the ampersand (`&`). Here's a simple
3410+
reference:
3411+
3412+
```{rust}
3413+
let x = 5i;
3414+
let y = &x;
3415+
```
3416+
3417+
`y` is a reference to `x`. To dereference (get the value being referred to
3418+
rather than the reference itself) `y`, we use the asterisk (`*`):
3419+
3420+
```{rust}
3421+
let x = 5i;
3422+
let y = &x;
3423+
3424+
assert_eq!(5i, *y);
3425+
```
3426+
3427+
Like any `let` binding, references are immutable by default.
3428+
3429+
You can declare that functions take a reference:
3430+
3431+
```{rust}
3432+
fn add_one(x: &int) -> int { *x + 1 }
3433+
3434+
fn main() {
3435+
assert_eq!(6, add_one(&5));
3436+
}
3437+
```
3438+
3439+
As you can see, we can make a reference from a literal by applying `&` as well.
3440+
Of course, in this simple function, there's not a lot of reason to take `x` by
3441+
reference. It's just an example of the syntax.
3442+
3443+
Because references are immutable, you can have multiple references that
3444+
**alias** (point to the same place):
3445+
3446+
```{rust}
3447+
let x = 5i;
3448+
let y = &x;
3449+
let z = &x;
3450+
```
3451+
3452+
We can make a mutable reference by using `&mut` instead of `&`:
3453+
3454+
```{rust}
3455+
let mut x = 5i;
3456+
let y = &mut x;
3457+
```
3458+
3459+
Note that `x` must also be mutable. If it isn't, like this:
3460+
3461+
```{rust,ignore}
3462+
let x = 5i;
3463+
let y = &mut x;
3464+
```
3465+
3466+
Rust will complain:
3467+
3468+
```{ignore,notrust}
3469+
6:19 error: cannot borrow immutable local variable `x` as mutable
3470+
let y = &mut x;
3471+
^
3472+
```
3473+
3474+
We don't want a mutable reference to immutable data! This error message uses a
3475+
term we haven't talked about yet, 'borrow.' We'll get to that in just a moment.
3476+
3477+
This simple example actually illustrates a lot of Rust's power: Rust has
3478+
prevented us, at compile time, from breaking our own rules. Because Rust's
3479+
references check these kinds of rules entirely at compile time, there's no
3480+
runtime overhead for this safety. At runtime, these are the same as a raw
3481+
machine pointer, like in C or C++. We've just double-checked ahead of time
3482+
that we haven't done anything dangerous.
3483+
3484+
Rust will also prevent us from creating two mutable references that alias.
3485+
This won't work:
3486+
3487+
```{rust,ignore}
3488+
let mut x = 5i;
3489+
let y = &mut x;
3490+
let z = &mut x;
3491+
```
3492+
3493+
It gives us this error:
3494+
3495+
```{notrust,ignore}
3496+
error: cannot borrow `x` as mutable more than once at a time
3497+
let z = &mut x;
3498+
^
3499+
note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
3500+
let y = &mut x;
3501+
^
3502+
note: previous borrow ends here
3503+
fn main() {
3504+
let mut x = 5i;
3505+
let y = &mut x;
3506+
let z = &mut x;
3507+
}
3508+
^
3509+
```
3510+
3511+
This is a big error message. Let's dig into it for a moment. There are three
3512+
parts: the error and two notes. The error says what we expected, we cannot have
3513+
two pointers that point to the same memory.
3514+
3515+
The two notes give some extra context. Rust's error messages often contain this
3516+
kind of extra information when the error is complex. Rust is telling us two
3517+
things: first, that the reason we cannot **borrow** `x` as `z` is that we
3518+
previously borrowed `x` as `y`. The second note shows where `y`'s borrowing
3519+
ends.
3520+
3521+
Wait, borrowing?
3522+
3523+
In order to truly understand this error, we have to learn a few new concepts:
3524+
**ownership**, **borrowing**, and **lifetimes**.
3525+
3526+
## Ownership, borrowing, and lifetimes
3527+
3528+
## Boxes
3529+
3530+
All of our references so far have been to variables we've created on the stack.
3531+
In Rust, the simplest way to allocate heap variables is using a *box*. To
3532+
create a box, use the `box` keyword:
3533+
3534+
```{rust}
3535+
let x = box 5i;
3536+
```
3537+
3538+
This allocates an integer `5` on the heap, and creates a binding `x` that
3539+
refers to it.. The great thing about boxed pointers is that we don't have to
3540+
manually free this allocation! If we write
3541+
3542+
```{rust}
3543+
{
3544+
let x = box 5i;
3545+
// do stuff
3546+
}
3547+
```
3548+
3549+
then Rust will automatically free `x` at the end of the block. This isn't
3550+
because Rust has a garbage collector -- it doesn't. Instead, Rust uses static
3551+
analysis to determine the *lifetime* of `x`, and then generates code to free it
3552+
once it's sure the `x` won't be used again. This Rust code will do the same
3553+
thing as the following C code:
3554+
3555+
```{c,ignore}
3556+
{
3557+
int *x = (int *)malloc(sizeof(int));
3558+
// do stuff
3559+
free(x);
3560+
}
3561+
```
3562+
3563+
This means we get the benefits of manual memory management, but the compiler
3564+
ensures that we don't do something wrong. We can't forget to `free` our memory.
3565+
3566+
Boxes are the sole owner of their contents, so you cannot take a mutable
3567+
reference to them and then use the original box:
3568+
3569+
```{rust,ignore}
3570+
let mut x = box 5i;
3571+
let y = &mut x;
3572+
3573+
*x; // you might expect 5, but this is actually an error
3574+
```
3575+
3576+
This gives us this error:
3577+
3578+
```{notrust,ignore}
3579+
8:7 error: cannot use `*x` because it was mutably borrowed
3580+
*x;
3581+
^~
3582+
6:19 note: borrow of `x` occurs here
3583+
let y = &mut x;
3584+
^
3585+
```
3586+
3587+
As long as `y` is borrowing the contents, we cannot use `x`. After `y` is
3588+
done borrowing the value, we can use it again. This works fine:
3589+
3590+
```{rust}
3591+
let mut x = box 5i;
3592+
3593+
{
3594+
let y = &mut x;
3595+
} // y goes out of scope at the end of the block
3596+
3597+
*x;
3598+
```
3599+
3600+
## Rc and Arc
3601+
3602+
Sometimes, you need to allocate something on the heap, but give out multiple
3603+
references to the memory. Rust's `Rc<T>` (pronounced 'arr cee tee') and
3604+
`Arc<T>` types (again, the `T` is for generics, we'll learn more later) provide
3605+
you with this ability. **Rc** stands for 'reference counted,' and **Arc** for
3606+
'atomically reference counted.' This is how Rust keeps track of the multiple
3607+
owners: every time we make a new reference to the `Rc<T>`, we add one to its
3608+
internal 'reference count.' Every time a reference goes out of scope, we
3609+
subtract one from the count. When the count is zero, the `Rc<T>` can be safely
3610+
deallocated. `Arc<T>` is almost identical to `Rc<T>`, except for one thing: The
3611+
'atomically' in 'Arc' means that increasing and decreasing the count uses a
3612+
thread-safe mechanism to do so. Why two types? `Rc<T>` is faster, so if you're
3613+
not in a multi-threaded scenario, you can have that advantage. Since we haven't
3614+
talked about threading yet in Rust, we'll show you `Rc<T>` for the rest of this
3615+
section.
3616+
3617+
To create an `Rc<T>`, use `Rc::new()`:
3618+
3619+
```{rust}
3620+
use std::rc::Rc;
3621+
3622+
let x = Rc::new(5i);
3623+
```
3624+
3625+
To create a second reference, use the `.clone()` method:
3626+
3627+
```{rust}
3628+
use std::rc::Rc;
3629+
3630+
let x = Rc::new(5i);
3631+
let y = x.clone();
3632+
```
3633+
3634+
The `Rc<T>` will live as long as any of its references are alive. After they
3635+
all go out of scope, the memory will be `free`d.
3636+
3637+
If you use `Rc<T>` or `Arc<T>`, you have to be careful about introducing
3638+
cycles. If you have two `Rc<T>`s that point to each other, the reference counts
3639+
will never drop to zero, and you'll have a memory leak. To learn more, check
3640+
out [the section on `Rc<T>` and `Arc<T>` in the pointers
3641+
guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
3642+
3643+
# Patterns
3644+
33903645
# Lambdas
33913646

33923647
# iterators
33933648

3394-
33953649
# Generics
33963650

33973651
# Traits
33983652

33993653
# Operators and built-in Traits
34003654

3401-
# Ownership and Lifetimes
3402-
3403-
Move vs. Copy
3404-
3405-
Allocation
3406-
34073655
# Tasks
34083656

34093657
# Macros

0 commit comments

Comments
 (0)