]> git.proxmox.com Git - rustc.git/blame - src/doc/book/box-syntax-and-patterns.md
New upstream version 1.16.0+dfsg1
[rustc.git] / src / doc / book / box-syntax-and-patterns.md
CommitLineData
c34b1796
AL
1% Box Syntax and Patterns
2
3Currently the only stable way to create a `Box` is via the `Box::new` method.
4Also it is not possible in stable Rust to destructure a `Box` in a match
5pattern. The unstable `box` keyword can be used to both create and destructure
6a `Box`. An example usage would be:
7
62682a34 8```rust
c34b1796
AL
9#![feature(box_syntax, box_patterns)]
10
11fn 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
28Note that these features are currently hidden behind the `box_syntax` (box
29creation) and `box_patterns` (destructuring and pattern matching) gates
30because the syntax may still change in the future.
31
32# Returning Pointers
33
34In many languages with pointers, you'd return a pointer from a function
35so as to avoid copying a large data structure. For example:
36
62682a34 37```rust
c34b1796
AL
38struct BigStruct {
39 one: i32,
40 two: i32,
476ff2be 41 // Etc.
c34b1796
AL
42 one_hundred: i32,
43}
44
45fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
46 Box::new(*x)
47}
48
49fn 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
60The idea is that by passing around a box, you're only copying a pointer, rather
62682a34 61than the hundred `i32`s that make up the `BigStruct`.
c34b1796
AL
62
63This is an antipattern in Rust. Instead, write this:
64
65```rust
66#![feature(box_syntax)]
67
68struct BigStruct {
69 one: i32,
70 two: i32,
476ff2be 71 // Etc.
c34b1796
AL
72 one_hundred: i32,
73}
74
75fn foo(x: Box<BigStruct>) -> BigStruct {
76 *x
77}
78
79fn 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
90This gives you flexibility without sacrificing performance.
91
92You may think that this gives us terrible performance: return a value and then
93immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
94smarter than that. There is no copy in this code. `main` allocates enough room
95for 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
98This is important enough that it bears repeating: pointers are not for
99optimizing returning values from your code. Allow the caller to choose how they
100want to use your output.