Skip to content

Commit 00d929d

Browse files
committedApr 2, 2015
Moved use of box_syntax unstable feature in docs to Unstable section.
Create a new section under the Unstable section for `box` syntax and patterns and removed their discussion from the Pointers section.
1 parent d528aa9 commit 00d929d

File tree

3 files changed

+103
-84
lines changed

3 files changed

+103
-84
lines changed
 

‎src/doc/trpl/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@
4343
* [Lang items](lang-items.md)
4444
* [Link args](link-args.md)
4545
* [Benchmark Tests](benchmark-tests.md)
46+
* [Box Syntax and Patterns](box-syntax-and-patterns.md)
4647
* [Conclusion](conclusion.md)
4748
* [Glossary](glossary.md)
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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.

‎src/doc/trpl/pointers.md

+2-84
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ fn main() {
574574
```
575575

576576
We can mutably borrow `x` multiple times, but only if x itself is mutable, and
577-
it may not be *simultaneously* borrowed:
577+
it may not be *simultaneously* borrowed:
578578

579579
```{rust,ignore}
580580
fn increment(x: &mut i32) {
@@ -595,8 +595,7 @@ Notice the signature of `increment()` requests a mutable reference.
595595

596596
## Best practices
597597

598-
Boxes are appropriate to use in two situations: Recursive data structures,
599-
and occasionally, when returning data.
598+
Boxes are most appropriate to use when defining recursive data structures.
600599

601600
### Recursive data structures
602601

@@ -630,14 +629,6 @@ we don't know the size, and therefore, we need to heap allocate our list.
630629
Working with recursive or other unknown-sized data structures is the primary
631630
use-case for boxes.
632631

633-
### Returning data
634-
635-
This is important enough to have its own section entirely. The TL;DR is this:
636-
you don't want to return pointers, even when you might in a language like C or
637-
C++.
638-
639-
See [Returning Pointers](#returning-pointers) below for more.
640-
641632
# Rc and Arc
642633

643634
This part is coming soon.
@@ -654,79 +645,6 @@ This part is coming soon.
654645

655646
This part is coming soon.
656647

657-
# Returning Pointers
658-
659-
In many languages with pointers, you'd return a pointer from a function
660-
so as to avoid copying a large data structure. For example:
661-
662-
```{rust}
663-
struct BigStruct {
664-
one: i32,
665-
two: i32,
666-
// etc
667-
one_hundred: i32,
668-
}
669-
670-
fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
671-
Box::new(*x)
672-
}
673-
674-
fn main() {
675-
let x = Box::new(BigStruct {
676-
one: 1,
677-
two: 2,
678-
one_hundred: 100,
679-
});
680-
681-
let y = foo(x);
682-
}
683-
```
684-
685-
The idea is that by passing around a box, you're only copying a pointer, rather
686-
than the hundred `int`s that make up the `BigStruct`.
687-
688-
This is an antipattern in Rust. Instead, write this:
689-
690-
```rust
691-
#![feature(box_syntax)]
692-
693-
struct BigStruct {
694-
one: i32,
695-
two: i32,
696-
// etc
697-
one_hundred: i32,
698-
}
699-
700-
fn foo(x: Box<BigStruct>) -> BigStruct {
701-
*x
702-
}
703-
704-
fn main() {
705-
let x = Box::new(BigStruct {
706-
one: 1,
707-
two: 2,
708-
one_hundred: 100,
709-
});
710-
711-
let y: Box<BigStruct> = box foo(x);
712-
}
713-
```
714-
715-
Note that this uses the `box_syntax` feature gate, so this syntax may change in
716-
the future.
717-
718-
This gives you flexibility without sacrificing performance.
719-
720-
You may think that this gives us terrible performance: return a value and then
721-
immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
722-
smarter than that. There is no copy in this code. `main` allocates enough room
723-
for the `box`, passes a pointer to that memory into `foo` as `x`, and then
724-
`foo` writes the value straight into the `Box<T>`.
725-
726-
This is important enough that it bears repeating: pointers are not for
727-
optimizing returning values from your code. Allow the caller to choose how they
728-
want to use your output.
729-
730648
# Creating your own Pointers
731649

732650
This part is coming soon.

0 commit comments

Comments
 (0)