Skip to content

Commit a74197e

Browse files
committed
Guide: pointers
Not the pointer guide, but the guide section on pointers. Adding a section about patterns for after this, as well.
1 parent 9826e80 commit a74197e

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
@@ -2814,23 +2814,271 @@ By just bringing the module into scope, we can keep one level of namespacing.
28142814

28152815
# Pointers
28162816

2817+
In systems programming, pointers are an incredibly important topic. Rust has a
2818+
very rich set of pointers, and they operate differently than in many other
2819+
languages. They are important enough that we have a specific [Pointer
2820+
Guide](/guide-pointers.html) that goes into pointers in much detail. In fact,
2821+
while you're currently reading this guide, which covers the language in broad
2822+
overview, there are a number of other guides that put a specific topic under a
2823+
microscope. You can find the list of guides on the [documentation index
2824+
page](/index.html#guides).
2825+
2826+
In this section, we'll assume that you're familiar with pointers as a general
2827+
concept. If you aren't, please read the [introduction to
2828+
pointers](/guide-pointers.html#an-introduction) section of the Pointer Guide,
2829+
and then come back here. We'll wait.
2830+
2831+
Got the gist? Great. Let's talk about pointers in Rust.
2832+
2833+
## References
2834+
2835+
The most primitive form of pointer in Rust is called a **reference**.
2836+
References are created using the ampersand (`&`). Here's a simple
2837+
reference:
2838+
2839+
```{rust}
2840+
let x = 5i;
2841+
let y = &x;
2842+
```
2843+
2844+
`y` is a reference to `x`. To dereference (get the value being referred to
2845+
rather than the reference itself) `y`, we use the asterisk (`*`):
2846+
2847+
```{rust}
2848+
let x = 5i;
2849+
let y = &x;
2850+
2851+
assert_eq!(5i, *y);
2852+
```
2853+
2854+
Like any `let` binding, references are immutable by default.
2855+
2856+
You can declare that functions take a reference:
2857+
2858+
```{rust}
2859+
fn add_one(x: &int) -> int { *x + 1 }
2860+
2861+
fn main() {
2862+
assert_eq!(6, add_one(&5));
2863+
}
2864+
```
2865+
2866+
As you can see, we can make a reference from a literal by applying `&` as well.
2867+
Of course, in this simple function, there's not a lot of reason to take `x` by
2868+
reference. It's just an example of the syntax.
2869+
2870+
Because references are immutable, you can have multiple references that
2871+
**alias** (point to the same place):
2872+
2873+
```{rust}
2874+
let x = 5i;
2875+
let y = &x;
2876+
let z = &x;
2877+
```
2878+
2879+
We can make a mutable reference by using `&mut` instead of `&`:
2880+
2881+
```{rust}
2882+
let mut x = 5i;
2883+
let y = &mut x;
2884+
```
2885+
2886+
Note that `x` must also be mutable. If it isn't, like this:
2887+
2888+
```{rust,ignore}
2889+
let x = 5i;
2890+
let y = &mut x;
2891+
```
2892+
2893+
Rust will complain:
2894+
2895+
```{ignore,notrust}
2896+
6:19 error: cannot borrow immutable local variable `x` as mutable
2897+
let y = &mut x;
2898+
^
2899+
```
2900+
2901+
We don't want a mutable reference to immutable data! This error message uses a
2902+
term we haven't talked about yet, 'borrow.' We'll get to that in just a moment.
2903+
2904+
This simple example actually illustrates a lot of Rust's power: Rust has
2905+
prevented us, at compile time, from breaking our own rules. Because Rust's
2906+
references check these kinds of rules entirely at compile time, there's no
2907+
runtime overhead for this safety. At runtime, these are the same as a raw
2908+
machine pointer, like in C or C++. We've just double-checked ahead of time
2909+
that we haven't done anything dangerous.
2910+
2911+
Rust will also prevent us from creating two mutable references that alias.
2912+
This won't work:
2913+
2914+
```{rust,ignore}
2915+
let mut x = 5i;
2916+
let y = &mut x;
2917+
let z = &mut x;
2918+
```
2919+
2920+
It gives us this error:
2921+
2922+
```{notrust,ignore}
2923+
error: cannot borrow `x` as mutable more than once at a time
2924+
let z = &mut x;
2925+
^
2926+
note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
2927+
let y = &mut x;
2928+
^
2929+
note: previous borrow ends here
2930+
fn main() {
2931+
let mut x = 5i;
2932+
let y = &mut x;
2933+
let z = &mut x;
2934+
}
2935+
^
2936+
```
2937+
2938+
This is a big error message. Let's dig into it for a moment. There are three
2939+
parts: the error and two notes. The error says what we expected, we cannot have
2940+
two pointers that point to the same memory.
2941+
2942+
The two notes give some extra context. Rust's error messages often contain this
2943+
kind of extra information when the error is complex. Rust is telling us two
2944+
things: first, that the reason we cannot **borrow** `x` as `z` is that we
2945+
previously borrowed `x` as `y`. The second note shows where `y`'s borrowing
2946+
ends.
2947+
2948+
Wait, borrowing?
2949+
2950+
In order to truly understand this error, we have to learn a few new concepts:
2951+
**ownership**, **borrowing**, and **lifetimes**.
2952+
2953+
## Ownership, borrowing, and lifetimes
2954+
2955+
## Boxes
2956+
2957+
All of our references so far have been to variables we've created on the stack.
2958+
In Rust, the simplest way to allocate heap variables is using a *box*. To
2959+
create a box, use the `box` keyword:
2960+
2961+
```{rust}
2962+
let x = box 5i;
2963+
```
2964+
2965+
This allocates an integer `5` on the heap, and creates a binding `x` that
2966+
refers to it.. The great thing about boxed pointers is that we don't have to
2967+
manually free this allocation! If we write
2968+
2969+
```{rust}
2970+
{
2971+
let x = box 5i;
2972+
// do stuff
2973+
}
2974+
```
2975+
2976+
then Rust will automatically free `x` at the end of the block. This isn't
2977+
because Rust has a garbage collector -- it doesn't. Instead, Rust uses static
2978+
analysis to determine the *lifetime* of `x`, and then generates code to free it
2979+
once it's sure the `x` won't be used again. This Rust code will do the same
2980+
thing as the following C code:
2981+
2982+
```{c,ignore}
2983+
{
2984+
int *x = (int *)malloc(sizeof(int));
2985+
// do stuff
2986+
free(x);
2987+
}
2988+
```
2989+
2990+
This means we get the benefits of manual memory management, but the compiler
2991+
ensures that we don't do something wrong. We can't forget to `free` our memory.
2992+
2993+
Boxes are the sole owner of their contents, so you cannot take a mutable
2994+
reference to them and then use the original box:
2995+
2996+
```{rust,ignore}
2997+
let mut x = box 5i;
2998+
let y = &mut x;
2999+
3000+
*x; // you might expect 5, but this is actually an error
3001+
```
3002+
3003+
This gives us this error:
3004+
3005+
```{notrust,ignore}
3006+
8:7 error: cannot use `*x` because it was mutably borrowed
3007+
*x;
3008+
^~
3009+
6:19 note: borrow of `x` occurs here
3010+
let y = &mut x;
3011+
^
3012+
```
3013+
3014+
As long as `y` is borrowing the contents, we cannot use `x`. After `y` is
3015+
done borrowing the value, we can use it again. This works fine:
3016+
3017+
```{rust}
3018+
let mut x = box 5i;
3019+
3020+
{
3021+
let y = &mut x;
3022+
} // y goes out of scope at the end of the block
3023+
3024+
*x;
3025+
```
3026+
3027+
## Rc and Arc
3028+
3029+
Sometimes, you need to allocate something on the heap, but give out multiple
3030+
references to the memory. Rust's `Rc<T>` (pronounced 'arr cee tee') and
3031+
`Arc<T>` types (again, the `T` is for generics, we'll learn more later) provide
3032+
you with this ability. **Rc** stands for 'reference counted,' and **Arc** for
3033+
'atomically reference counted.' This is how Rust keeps track of the multiple
3034+
owners: every time we make a new reference to the `Rc<T>`, we add one to its
3035+
internal 'reference count.' Every time a reference goes out of scope, we
3036+
subtract one from the count. When the count is zero, the `Rc<T>` can be safely
3037+
deallocated. `Arc<T>` is almost identical to `Rc<T>`, except for one thing: The
3038+
'atomically' in 'Arc' means that increasing and decreasing the count uses a
3039+
thread-safe mechanism to do so. Why two types? `Rc<T>` is faster, so if you're
3040+
not in a multi-threaded scenario, you can have that advantage. Since we haven't
3041+
talked about threading yet in Rust, we'll show you `Rc<T>` for the rest of this
3042+
section.
3043+
3044+
To create an `Rc<T>`, use `Rc::new()`:
3045+
3046+
```{rust}
3047+
use std::rc::Rc;
3048+
3049+
let x = Rc::new(5i);
3050+
```
3051+
3052+
To create a second reference, use the `.clone()` method:
3053+
3054+
```{rust}
3055+
use std::rc::Rc;
3056+
3057+
let x = Rc::new(5i);
3058+
let y = x.clone();
3059+
```
3060+
3061+
The `Rc<T>` will live as long as any of its references are alive. After they
3062+
all go out of scope, the memory will be `free`d.
3063+
3064+
If you use `Rc<T>` or `Arc<T>`, you have to be careful about introducing
3065+
cycles. If you have two `Rc<T>`s that point to each other, the reference counts
3066+
will never drop to zero, and you'll have a memory leak. To learn more, check
3067+
out [the section on `Rc<T>` and `Arc<T>` in the pointers
3068+
guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
3069+
3070+
# Patterns
3071+
28173072
# Lambdas
28183073

28193074
# iterators
28203075

2821-
28223076
# Generics
28233077

28243078
# Traits
28253079

28263080
# Operators and built-in Traits
28273081

2828-
# Ownership and Lifetimes
2829-
2830-
Move vs. Copy
2831-
2832-
Allocation
2833-
28343082
# Tasks
28353083

28363084
# Macros

0 commit comments

Comments
 (0)