]> git.proxmox.com Git - rustc.git/blob - src/doc/trpl/box-syntax-and-patterns.md
839f07d9843226560fd27d2165e113f51905f84f
[rustc.git] / src / doc / trpl / box-syntax-and-patterns.md
1 % Box Syntax and Patterns
2
3 Currently the only stable way to create a `Box` is via the `Box::new` method.
4 Also it is not possible in stable Rust to destructure a `Box` in a match
5 pattern. The unstable `box` keyword can be used to both create and destructure
6 a `Box`. An example usage would be:
7
8 ```
9 #![feature(box_syntax, box_patterns)]
10
11 fn main() {
12 let b = Some(box 5);
13 match b {
14 Some(box n) if n < 0 => {
15 println!("Box contains negative number {}", n);
16 },
17 Some(box n) if n >= 0 => {
18 println!("Box contains non-negative number {}", n);
19 },
20 None => {
21 println!("No box");
22 },
23 _ => unreachable!()
24 }
25 }
26 ```
27
28 Note that these features are currently hidden behind the `box_syntax` (box
29 creation) and `box_patterns` (destructuring and pattern matching) gates
30 because the syntax may still change in the future.
31
32 # Returning Pointers
33
34 In many languages with pointers, you'd return a pointer from a function
35 so as to avoid copying a large data structure. For example:
36
37 ```{rust}
38 struct BigStruct {
39 one: i32,
40 two: i32,
41 // etc
42 one_hundred: i32,
43 }
44
45 fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
46 Box::new(*x)
47 }
48
49 fn main() {
50 let x = Box::new(BigStruct {
51 one: 1,
52 two: 2,
53 one_hundred: 100,
54 });
55
56 let y = foo(x);
57 }
58 ```
59
60 The idea is that by passing around a box, you're only copying a pointer, rather
61 than the hundred `int`s that make up the `BigStruct`.
62
63 This is an antipattern in Rust. Instead, write this:
64
65 ```rust
66 #![feature(box_syntax)]
67
68 struct BigStruct {
69 one: i32,
70 two: i32,
71 // etc
72 one_hundred: i32,
73 }
74
75 fn foo(x: Box<BigStruct>) -> BigStruct {
76 *x
77 }
78
79 fn main() {
80 let x = Box::new(BigStruct {
81 one: 1,
82 two: 2,
83 one_hundred: 100,
84 });
85
86 let y: Box<BigStruct> = box foo(x);
87 }
88 ```
89
90 This gives you flexibility without sacrificing performance.
91
92 You may think that this gives us terrible performance: return a value and then
93 immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
94 smarter than that. There is no copy in this code. `main` allocates enough room
95 for the `box`, passes a pointer to that memory into `foo` as `x`, and then
96 `foo` writes the value straight into the `Box<T>`.
97
98 This is important enough that it bears repeating: pointers are not for
99 optimizing returning values from your code. Allow the caller to choose how they
100 want to use your output.