]> git.lizzy.rs Git - rust.git/blob - src/doc/guide-pointers.md
rollup merge of #20731: nick29581/assoc-inherant
[rust.git] / src / doc / guide-pointers.md
1 % The Rust Pointer Guide
2
3 Rust's pointers are one of its more unique and compelling features. Pointers
4 are also one of the more confusing topics for newcomers to Rust. They can also
5 be confusing for people coming from other languages that support pointers, such
6 as C++. This guide will help you understand this important topic.
7
8 Be sceptical of non-reference pointers in Rust: use them for a deliberate
9 purpose, not just to make the compiler happy. Each pointer type comes with an
10 explanation about when they are appropriate to use. Default to references
11 unless you're in one of those specific situations.
12
13 You may be interested in the [cheat sheet](#cheat-sheet), which gives a quick
14 overview of the types, names, and purpose of the various pointers.
15
16 # An introduction
17
18 If you aren't familiar with the concept of pointers, here's a short
19 introduction.  Pointers are a very fundamental concept in systems programming
20 languages, so it's important to understand them.
21
22 ## Pointer Basics
23
24 When you create a new variable binding, you're giving a name to a value that's
25 stored at a particular location on the stack. (If you're not familiar with the
26 "heap" vs. "stack", please check out [this Stack Overflow
27 question](http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap),
28 as the rest of this guide assumes you know the difference.) Like this:
29
30 ```{rust}
31 let x = 5i;
32 let y = 8i;
33 ```
34 | location | value |
35 |----------|-------|
36 | 0xd3e030 | 5     |
37 | 0xd3e028 | 8     |
38
39 We're making up memory locations here, they're just sample values. Anyway, the
40 point is that `x`, the name we're using for our variable, corresponds to the
41 memory location `0xd3e030`, and the value at that location is `5`. When we
42 refer to `x`, we get the corresponding value. Hence, `x` is `5`.
43
44 Let's introduce a pointer. In some languages, there is just one type of
45 'pointer,' but in Rust, we have many types. In this case, we'll use a Rust
46 **reference**, which is the simplest kind of pointer.
47
48 ```{rust}
49 let x = 5i;
50 let y = 8i;
51 let z = &y;
52 ```
53 |location | value    |
54 |-------- |----------|
55 |0xd3e030 | 5        |
56 |0xd3e028 | 8        |
57 |0xd3e020 | 0xd3e028 |
58
59 See the difference? Rather than contain a value, the value of a pointer is a
60 location in memory. In this case, the location of `y`. `x` and `y` have the
61 type `int`, but `z` has the type `&int`. We can print this location using the
62 `{:p}` format string:
63
64 ```{rust}
65 let x = 5i;
66 let y = 8i;
67 let z = &y;
68
69 println!("{:p}", z);
70 ```
71
72 This would print `0xd3e028`, with our fictional memory addresses.
73
74 Because `int` and `&int` are different types, we can't, for example, add them
75 together:
76
77 ```{rust,ignore}
78 let x = 5i;
79 let y = 8i;
80 let z = &y;
81
82 println!("{}", x + z);
83 ```
84
85 This gives us an error:
86
87 ```text
88 hello.rs:6:24: 6:25 error: mismatched types: expected `int` but found `&int` (expected int but found &-ptr)
89 hello.rs:6     println!("{}", x + z);
90                                   ^
91 ```
92
93 We can **dereference** the pointer by using the `*` operator. Dereferencing a
94 pointer means accessing the value at the location stored in the pointer. This
95 will work:
96
97 ```{rust}
98 let x = 5i;
99 let y = 8i;
100 let z = &y;
101
102 println!("{}", x + *z);
103 ```
104
105 It prints `13`.
106
107 That's it! That's all pointers are: they point to some memory location. Not
108 much else to them. Now that we've discussed the 'what' of pointers, let's
109 talk about the 'why.'
110
111 ## Pointer uses
112
113 Rust's pointers are quite useful, but in different ways than in other systems
114 languages. We'll talk about best practices for Rust pointers later in
115 the guide, but here are some ways that pointers are useful in other languages:
116
117 In C, strings are a pointer to a list of `char`s, ending with a null byte.
118 The only way to use strings is to get quite familiar with pointers.
119
120 Pointers are useful to point to memory locations that are not on the stack. For
121 example, our example used two stack variables, so we were able to give them
122 names. But if we allocated some heap memory, we wouldn't have that name
123 available.  In C, `malloc` is used to allocate heap memory, and it returns a
124 pointer.
125
126 As a more general variant of the previous two points, any time you have a
127 structure that can change in size, you need a pointer. You can't tell at
128 compile time how much memory to allocate, so you've gotta use a pointer to
129 point at the memory where it will be allocated, and deal with it at run time.
130
131 Pointers are useful in languages that are pass-by-value, rather than
132 pass-by-reference. Basically, languages can make two choices (this is made
133 up syntax, it's not Rust):
134
135 ```text
136 func foo(x) {
137     x = 5
138 }
139
140 func main() {
141     i = 1
142     foo(i)
143     // what is the value of i here?
144 }
145 ```
146
147 In languages that are pass-by-value, `foo` will get a copy of `i`, and so
148 the original version of `i` is not modified. At the comment, `i` will still be
149 `1`. In a language that is pass-by-reference, `foo` will get a reference to `i`,
150 and therefore, can change its value. At the comment, `i` will be `5`.
151
152 So what do pointers have to do with this? Well, since pointers point to a
153 location in memory...
154
155 ```text
156 func foo(&int x) {
157     *x = 5
158 }
159
160 func main() {
161     i = 1
162     foo(&i)
163     // what is the value of i here?
164 }
165 ```
166
167 Even in a language which is pass by value, `i` will be `5` at the comment. You
168 see, because the argument `x` is a pointer, we do send a copy over to `foo`,
169 but because it points at a memory location, which we then assign to, the
170 original value is still changed. This pattern is called
171 'pass-reference-by-value.' Tricky!
172
173 ## Common pointer problems
174
175 We've talked about pointers, and we've sung their praises. So what's the
176 downside? Well, Rust attempts to mitigate each of these kinds of problems,
177 but here are problems with pointers in other languages:
178
179 Uninitialized pointers can cause a problem. For example, what does this program
180 do?
181
182 ```{ignore}
183 &int x;
184 *x = 5; // whoops!
185 ```
186
187 Who knows? We just declare a pointer, but don't point it at anything, and then
188 set the memory location that it points at to be `5`. But which location? Nobody
189 knows. This might be harmless, and it might be catastrophic.
190
191 When you combine pointers and functions, it's easy to accidentally invalidate
192 the memory the pointer is pointing to. For example:
193
194 ```text
195 func make_pointer(): &int {
196     x = 5;
197
198     return &x;
199 }
200
201 func main() {
202     &int i = make_pointer();
203     *i = 5; // uh oh!
204 }
205 ```
206
207 `x` is local to the `make_pointer` function, and therefore, is invalid as soon
208 as `make_pointer` returns. But we return a pointer to its memory location, and
209 so back in `main`, we try to use that pointer, and it's a very similar
210 situation to our first one. Setting invalid memory locations is bad.
211
212 As one last example of a big problem with pointers, **aliasing** can be an
213 issue. Two pointers are said to alias when they point at the same location
214 in memory. Like this:
215
216 ```text
217 func mutate(&int i, int j) {
218     *i = j;
219 }
220
221 func main() {
222   x = 5;
223   y = &x;
224   z = &x; //y and z are aliased
225
226
227   run_in_new_thread(mutate, y, 1);
228   run_in_new_thread(mutate, z, 100);
229
230   // what is the value of x here?
231 }
232 ```
233
234 In this made-up example, `run_in_new_thread` spins up a new thread, and calls
235 the given function name with its arguments. Since we have two threads, and
236 they're both operating on aliases to `x`, we can't tell which one finishes
237 first, and therefore, the value of `x` is actually non-deterministic. Worse,
238 what if one of them had invalidated the memory location they pointed to? We'd
239 have the same problem as before, where we'd be setting an invalid location.
240
241 ## Conclusion
242
243 That's a basic overview of pointers as a general concept. As we alluded to
244 before, Rust has different kinds of pointers, rather than just one, and
245 mitigates all of the problems that we talked about, too. This does mean that
246 Rust pointers are slightly more complicated than in other languages, but
247 it's worth it to not have the problems that simple pointers have.
248
249 # References
250
251 The most basic type of pointer that Rust has is called a 'reference.' Rust
252 references look like this:
253
254 ```{rust}
255 let x = 5i;
256 let y = &x;
257
258 println!("{}", *y);
259 println!("{:p}", y);
260 println!("{}", y);
261 ```
262
263 We'd say "`y` is a reference to `x`." The first `println!` prints out the
264 value of `y`'s referent by using the dereference operator, `*`. The second
265 one prints out the memory location that `y` points to, by using the pointer
266 format string. The third `println!` *also* prints out the value of `y`'s
267 referent, because `println!` will automatically dereference it for us.
268
269 Here's a function that takes a reference:
270
271 ```{rust}
272 fn succ(x: &int) -> int { *x + 1 }
273 ```
274
275 You can also use `&` as an operator to create a reference, so we can
276 call this function in two different ways:
277
278 ```{rust}
279 fn succ(x: &int) -> int { *x + 1 }
280
281 fn main() {
282
283     let x = 5i;
284     let y = &x;
285
286     println!("{}", succ(y));
287     println!("{}", succ(&x));
288 }
289 ```
290
291 Both of these `println!`s will print out `6`.
292
293 Of course, if this were real code, we wouldn't bother with the reference, and
294 just write:
295
296 ```{rust}
297 fn succ(x: int) -> int { x + 1 }
298 ```
299
300 References are immutable by default:
301
302 ```{rust,ignore}
303 let x = 5i;
304 let y = &x;
305
306 *y = 5; // error: cannot assign to immutable dereference of `&`-pointer `*y`
307 ```
308
309 They can be made mutable with `mut`, but only if its referent is also mutable.
310 This works:
311
312 ```{rust}
313 let mut x = 5i;
314 let y = &mut x;
315 ```
316
317 This does not:
318
319 ```{rust,ignore}
320 let x = 5i;
321 let y = &mut x; // error: cannot borrow immutable local variable `x` as mutable
322 ```
323
324 Immutable pointers are allowed to alias:
325
326 ```{rust}
327 let x = 5i;
328 let y = &x;
329 let z = &x;
330 ```
331
332 Mutable ones, however, are not:
333
334 ```{rust,ignore}
335 let mut x = 5i;
336 let y = &mut x;
337 let z = &mut x; // error: cannot borrow `x` as mutable more than once at a time
338 ```
339
340 Despite their complete safety, a reference's representation at runtime is the
341 same as that of an ordinary pointer in a C program. They introduce zero
342 overhead. The compiler does all safety checks at compile time. The theory that
343 allows for this was originally called **region pointers**. Region pointers
344 evolved into what we know today as **lifetimes**.
345
346 Here's the simple explanation: would you expect this code to compile?
347
348 ```{rust,ignore}
349 fn main() {
350     println!("{}", x);
351     let x = 5;
352 }
353 ```
354
355 Probably not. That's because you know that the name `x` is valid from where
356 it's declared to when it goes out of scope. In this case, that's the end of
357 the `main` function. So you know this code will cause an error. We call this
358 duration a 'lifetime'. Let's try a more complex example:
359
360 ```{rust}
361 fn main() {
362     let x = &mut 5i;
363
364     if *x < 10 {
365         let y = &x;
366
367         println!("Oh no: {}", y);
368         return;
369     }
370
371     *x -= 1;
372
373     println!("Oh no: {}", x);
374 }
375 ```
376
377 Here, we're borrowing a pointer to `x` inside of the `if`. The compiler, however,
378 is able to determine that that pointer will go out of scope without `x` being
379 mutated, and therefore, lets us pass. This wouldn't work:
380
381 ```{rust,ignore}
382 fn main() {
383     let x = &mut 5i;
384
385     if *x < 10 {
386         let y = &x;
387         *x -= 1;
388
389         println!("Oh no: {}", y);
390         return;
391     }
392
393     *x -= 1;
394
395     println!("Oh no: {}", x);
396 }
397 ```
398
399 It gives this error:
400
401 ```text
402 test.rs:5:8: 5:10 error: cannot assign to `*x` because it is borrowed
403 test.rs:5         *x -= 1;
404                   ^~
405 test.rs:4:16: 4:18 note: borrow of `*x` occurs here
406 test.rs:4         let y = &x;
407                           ^~
408 ```
409
410 As you might guess, this kind of analysis is complex for a human, and therefore
411 hard for a computer, too! There is an entire [guide devoted to references, ownership,
412 and lifetimes](guide-ownership.html) that goes into this topic in
413 great detail, so if you want the full details, check that out.
414
415 ## Best practices
416
417 In general, prefer stack allocation over heap allocation. Using references to
418 stack allocated information is preferred whenever possible. Therefore,
419 references are the default pointer type you should use, unless you have a
420 specific reason to use a different type. The other types of pointers cover when
421 they're appropriate to use in their own best practices sections.
422
423 Use references when you want to use a pointer, but do not want to take ownership.
424 References just borrow ownership, which is more polite if you don't need the
425 ownership. In other words, prefer:
426
427 ```{rust}
428 fn succ(x: &int) -> int { *x + 1 }
429 ```
430
431 to
432
433 ```{rust}
434 fn succ(x: Box<int>) -> int { *x + 1 }
435 ```
436
437 As a corollary to that rule, references allow you to accept a wide variety of
438 other pointers, and so are useful so that you don't have to write a number
439 of variants per pointer. In other words, prefer:
440
441 ```{rust}
442 fn succ(x: &int) -> int { *x + 1 }
443 ```
444
445 to
446
447 ```{rust}
448 use std::rc::Rc;
449
450 fn box_succ(x: Box<int>) -> int { *x + 1 }
451
452 fn rc_succ(x: Rc<int>) -> int { *x + 1 }
453 ```
454
455 Note that the caller of your function will have to modify their calls slightly:
456
457 ```{rust}
458 # use std::boxed::Box;
459 use std::rc::Rc;
460
461 fn succ(x: &int) -> int { *x + 1 }
462
463 let ref_x = &5i;
464 let box_x = Box::new(5i);
465 let rc_x  = Rc::new(5i);
466
467 succ(ref_x);
468 succ(&*box_x);
469 succ(&*rc_x);
470 ```
471
472 The initial `*` dereferences the pointer, and then `&` takes a reference to
473 those contents.
474
475 # Boxes
476
477 `Box<T>` is Rust's 'boxed pointer' type. Boxes provide the simplest form of
478 heap allocation in Rust. Creating a box looks like this:
479
480 ```{rust}
481 # use std::boxed::Box;
482 let x = Box::new(5i);
483 ```
484
485 Boxes are heap allocated and they are deallocated automatically by Rust when
486 they go out of scope:
487
488 ```{rust}
489 # use std::boxed::Box;
490 {
491     let x = Box::new(5i);
492
493     // stuff happens
494
495 } // x is destructed and its memory is free'd here
496 ```
497
498 However, boxes do _not_ use reference counting or garbage collection. Boxes are
499 what's called an **affine type**. This means that the Rust compiler, at compile
500 time, determines when the box comes into and goes out of scope, and inserts the
501 appropriate calls there. Furthermore, boxes are a specific kind of affine type,
502 known as a **region**. You can read more about regions [in this paper on the
503 Cyclone programming
504 language](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf).
505
506 You don't need to fully grok the theory of affine types or regions to grok
507 boxes, though. As a rough approximation, you can treat this Rust code:
508
509 ```{rust}
510 # use std::boxed::Box;
511 {
512     let x = Box::new(5i);
513
514     // stuff happens
515 }
516 ```
517
518 As being similar to this C code:
519
520 ```c
521 {
522     int *x;
523     x = (int *)malloc(sizeof(int));
524     *x = 5;
525
526     // stuff happens
527
528     free(x);
529 }
530 ```
531
532 Of course, this is a 10,000 foot view. It leaves out destructors, for example.
533 But the general idea is correct: you get the semantics of `malloc`/`free`, but
534 with some improvements:
535
536 1. It's impossible to allocate the incorrect amount of memory, because Rust
537    figures it out from the types.
538 2. You cannot forget to `free` memory you've allocated, because Rust does it
539    for you.
540 3. Rust ensures that this `free` happens at the right time, when it is truly
541    not used. Use-after-free is not possible.
542 4. Rust enforces that no other writeable pointers alias to this heap memory,
543    which means writing to an invalid pointer is not possible.
544
545 See the section on references or the [ownership guide](guide-ownership.html)
546 for more detail on how lifetimes work.
547
548 Using boxes and references together is very common. For example:
549
550 ```{rust}
551 # use std::boxed::Box;
552 fn add_one(x: &int) -> int {
553     *x + 1
554 }
555
556 fn main() {
557     let x = Box::new(5i);
558
559     println!("{}", add_one(&*x));
560 }
561 ```
562
563 In this case, Rust knows that `x` is being 'borrowed' by the `add_one()`
564 function, and since it's only reading the value, allows it.
565
566 We can borrow `x` multiple times, as long as it's not simultaneous:
567
568 ```{rust}
569 # use std::boxed::Box;
570 fn add_one(x: &int) -> int {
571     *x + 1
572 }
573
574 fn main() {
575     let x = Box::new(5i);
576
577     println!("{}", add_one(&*x));
578     println!("{}", add_one(&*x));
579     println!("{}", add_one(&*x));
580 }
581 ```
582
583 Or as long as it's not a mutable borrow. This will error:
584
585 ```{rust,ignore}
586 # use std::boxed::Box;
587 fn add_one(x: &mut int) -> int {
588     *x + 1
589 }
590
591 fn main() {
592     let x = Box::new(5i);
593
594     println!("{}", add_one(&*x)); // error: cannot borrow immutable dereference
595                                   // of `&`-pointer as mutable
596 }
597 ```
598
599 Notice we changed the signature of `add_one()` to request a mutable reference.
600
601 ## Best practices
602
603 Boxes are appropriate to use in two situations: Recursive data structures,
604 and occasionally, when returning data.
605
606 ### Recursive data structures
607
608 Sometimes, you need a recursive data structure. The simplest is known as a
609 'cons list':
610
611
612 ```{rust}
613 # use std::boxed::Box;
614 #[derive(Show)]
615 enum List<T> {
616     Cons(T, Box<List<T>>),
617     Nil,
618 }
619
620 fn main() {
621     let list: List<int> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
622     println!("{:?}", list);
623 }
624 ```
625
626 This prints:
627
628 ```text
629 Cons(1, Box(Cons(2, Box(Cons(3, Box(Nil))))))
630 ```
631
632 The reference to another `List` inside of the `Cons` enum variant must be a box,
633 because we don't know the length of the list. Because we don't know the length,
634 we don't know the size, and therefore, we need to heap allocate our list.
635
636 Working with recursive or other unknown-sized data structures is the primary
637 use-case for boxes.
638
639 ### Returning data
640
641 This is important enough to have its own section entirely. The TL;DR is this:
642 you don't generally want to return pointers, even when you might in a language
643 like C or C++.
644
645 See [Returning Pointers](#returning-pointers) below for more.
646
647 # Rc and Arc
648
649 This part is coming soon.
650
651 ## Best practices
652
653 This part is coming soon.
654
655 # Raw Pointers
656
657 This part is coming soon.
658
659 ## Best practices
660
661 This part is coming soon.
662
663 # Returning Pointers
664
665 In many languages with pointers, you'd return a pointer from a function
666 so as to avoid copying a large data structure. For example:
667
668 ```{rust}
669 # use std::boxed::Box;
670 struct BigStruct {
671     one: int,
672     two: int,
673     // etc
674     one_hundred: int,
675 }
676
677 fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
678     return Box::new(*x);
679 }
680
681 fn main() {
682     let x = Box::new(BigStruct {
683         one: 1,
684         two: 2,
685         one_hundred: 100,
686     });
687
688     let y = foo(x);
689 }
690 ```
691
692 The idea is that by passing around a box, you're only copying a pointer, rather
693 than the hundred `int`s that make up the `BigStruct`.
694
695 This is an antipattern in Rust. Instead, write this:
696
697 ```{rust}
698 # use std::boxed::Box;
699 struct BigStruct {
700     one: int,
701     two: int,
702     // etc
703     one_hundred: int,
704 }
705
706 fn foo(x: Box<BigStruct>) -> BigStruct {
707     return *x;
708 }
709
710 fn main() {
711     let x = Box::new(BigStruct {
712         one: 1,
713         two: 2,
714         one_hundred: 100,
715     });
716
717     let y = Box::new(foo(x));
718 }
719 ```
720
721 This gives you flexibility without sacrificing performance.
722
723 You may think that this gives us terrible performance: return a value and then
724 immediately box it up ?! Isn't that the worst of both worlds? Rust is smarter
725 than that. There is no copy in this code. `main` allocates enough room for the
726 `box`, passes a pointer to that memory into `foo` as `x`, and then `foo` writes
727 the value straight into that pointer. This writes the return value directly into
728 the allocated box.
729
730 This is important enough that it bears repeating: pointers are not for
731 optimizing returning values from your code. Allow the caller to choose how they
732 want to use your output.
733
734 # Creating your own Pointers
735
736 This part is coming soon.
737
738 ## Best practices
739
740 This part is coming soon.
741
742 # Patterns and `ref`
743
744 When you're trying to match something that's stored in a pointer, there may be
745 a situation where matching directly isn't the best option available. Let's see
746 how to properly handle this:
747
748 ```{rust,ignore}
749 fn possibly_print(x: &Option<String>) {
750     match *x {
751         // BAD: cannot move out of a `&`
752         Some(s) => println!("{}", s)
753
754         // GOOD: instead take a reference into the memory of the `Option`
755         Some(ref s) => println!("{}", *s),
756         None => {}
757     }
758 }
759 ```
760
761 The `ref s` here means that `s` will be of type `&String`, rather than type
762 `String`.
763
764 This is important when the type you're trying to get access to has a destructor
765 and you don't want to move it, you just want a reference to it.
766
767 # Cheat Sheet
768
769 Here's a quick rundown of Rust's pointer types:
770
771 | Type         | Name                | Summary                                                             |
772 |--------------|---------------------|---------------------------------------------------------------------|
773 | `&T`         | Reference           | Allows one or more references to read `T`                           |
774 | `&mut T`     | Mutable Reference   | Allows a single reference to read and write `T`                     |
775 | `Box<T>`     | Box                 | Heap allocated `T` with a single owner that may read and write `T`. |
776 | `Rc<T>`      | "arr cee" pointer   | Heap allocated `T` with many readers                                |
777 | `Arc<T>`     | Arc pointer         | Same as above, but safe sharing across threads                      |
778 | `*const T`   | Raw pointer         | Unsafe read access to `T`                                           |
779 | `*mut T`     | Mutable raw pointer | Unsafe read and write access to `T`                                 |
780
781 # Related resources
782
783 * [API documentation for Box](std/boxed/index.html)
784 * [Ownership guide](guide-ownership.html)
785 * [Cyclone paper on regions](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf), which inspired Rust's lifetime system