mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
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.
This commit is contained in:
parent
d528aa9960
commit
00d929dcb3
@ -43,5 +43,6 @@
|
|||||||
* [Lang items](lang-items.md)
|
* [Lang items](lang-items.md)
|
||||||
* [Link args](link-args.md)
|
* [Link args](link-args.md)
|
||||||
* [Benchmark Tests](benchmark-tests.md)
|
* [Benchmark Tests](benchmark-tests.md)
|
||||||
|
* [Box Syntax and Patterns](box-syntax-and-patterns.md)
|
||||||
* [Conclusion](conclusion.md)
|
* [Conclusion](conclusion.md)
|
||||||
* [Glossary](glossary.md)
|
* [Glossary](glossary.md)
|
||||||
|
100
src/doc/trpl/box-syntax-and-patterns.md
Normal file
100
src/doc/trpl/box-syntax-and-patterns.md
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
% Box Syntax and Patterns
|
||||||
|
|
||||||
|
Currently the only stable way to create a `Box` is via the `Box::new` method.
|
||||||
|
Also it is not possible in stable Rust to destructure a `Box` in a match
|
||||||
|
pattern. The unstable `box` keyword can be used to both create and destructure
|
||||||
|
a `Box`. An example usage would be:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![feature(box_syntax, box_patterns)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let b = Some(box 5);
|
||||||
|
match b {
|
||||||
|
Some(box n) if n < 0 => {
|
||||||
|
println!("Box contains negative number {}", n);
|
||||||
|
},
|
||||||
|
Some(box n) if n >= 0 => {
|
||||||
|
println!("Box contains non-negative number {}", n);
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
println!("No box");
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that these features are currently hidden behind the `box_syntax` (box
|
||||||
|
creation) and `box_patterns` (destructuring and pattern matching) gates
|
||||||
|
because the syntax may still change in the future.
|
||||||
|
|
||||||
|
# Returning Pointers
|
||||||
|
|
||||||
|
In many languages with pointers, you'd return a pointer from a function
|
||||||
|
so as to avoid copying a large data structure. For example:
|
||||||
|
|
||||||
|
```{rust}
|
||||||
|
struct BigStruct {
|
||||||
|
one: i32,
|
||||||
|
two: i32,
|
||||||
|
// etc
|
||||||
|
one_hundred: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
|
||||||
|
Box::new(*x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Box::new(BigStruct {
|
||||||
|
one: 1,
|
||||||
|
two: 2,
|
||||||
|
one_hundred: 100,
|
||||||
|
});
|
||||||
|
|
||||||
|
let y = foo(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The idea is that by passing around a box, you're only copying a pointer, rather
|
||||||
|
than the hundred `int`s that make up the `BigStruct`.
|
||||||
|
|
||||||
|
This is an antipattern in Rust. Instead, write this:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
|
struct BigStruct {
|
||||||
|
one: i32,
|
||||||
|
two: i32,
|
||||||
|
// etc
|
||||||
|
one_hundred: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(x: Box<BigStruct>) -> BigStruct {
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Box::new(BigStruct {
|
||||||
|
one: 1,
|
||||||
|
two: 2,
|
||||||
|
one_hundred: 100,
|
||||||
|
});
|
||||||
|
|
||||||
|
let y: Box<BigStruct> = box foo(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This gives you flexibility without sacrificing performance.
|
||||||
|
|
||||||
|
You may think that this gives us terrible performance: return a value and then
|
||||||
|
immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
|
||||||
|
smarter than that. There is no copy in this code. `main` allocates enough room
|
||||||
|
for the `box`, passes a pointer to that memory into `foo` as `x`, and then
|
||||||
|
`foo` writes the value straight into the `Box<T>`.
|
||||||
|
|
||||||
|
This is important enough that it bears repeating: pointers are not for
|
||||||
|
optimizing returning values from your code. Allow the caller to choose how they
|
||||||
|
want to use your output.
|
@ -574,7 +574,7 @@ fn main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
We can mutably borrow `x` multiple times, but only if x itself is mutable, and
|
We can mutably borrow `x` multiple times, but only if x itself is mutable, and
|
||||||
it may not be *simultaneously* borrowed:
|
it may not be *simultaneously* borrowed:
|
||||||
|
|
||||||
```{rust,ignore}
|
```{rust,ignore}
|
||||||
fn increment(x: &mut i32) {
|
fn increment(x: &mut i32) {
|
||||||
@ -595,8 +595,7 @@ Notice the signature of `increment()` requests a mutable reference.
|
|||||||
|
|
||||||
## Best practices
|
## Best practices
|
||||||
|
|
||||||
Boxes are appropriate to use in two situations: Recursive data structures,
|
Boxes are most appropriate to use when defining recursive data structures.
|
||||||
and occasionally, when returning data.
|
|
||||||
|
|
||||||
### Recursive data structures
|
### Recursive data structures
|
||||||
|
|
||||||
@ -630,14 +629,6 @@ we don't know the size, and therefore, we need to heap allocate our list.
|
|||||||
Working with recursive or other unknown-sized data structures is the primary
|
Working with recursive or other unknown-sized data structures is the primary
|
||||||
use-case for boxes.
|
use-case for boxes.
|
||||||
|
|
||||||
### Returning data
|
|
||||||
|
|
||||||
This is important enough to have its own section entirely. The TL;DR is this:
|
|
||||||
you don't want to return pointers, even when you might in a language like C or
|
|
||||||
C++.
|
|
||||||
|
|
||||||
See [Returning Pointers](#returning-pointers) below for more.
|
|
||||||
|
|
||||||
# Rc and Arc
|
# Rc and Arc
|
||||||
|
|
||||||
This part is coming soon.
|
This part is coming soon.
|
||||||
@ -654,79 +645,6 @@ This part is coming soon.
|
|||||||
|
|
||||||
This part is coming soon.
|
This part is coming soon.
|
||||||
|
|
||||||
# Returning Pointers
|
|
||||||
|
|
||||||
In many languages with pointers, you'd return a pointer from a function
|
|
||||||
so as to avoid copying a large data structure. For example:
|
|
||||||
|
|
||||||
```{rust}
|
|
||||||
struct BigStruct {
|
|
||||||
one: i32,
|
|
||||||
two: i32,
|
|
||||||
// etc
|
|
||||||
one_hundred: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
|
|
||||||
Box::new(*x)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let x = Box::new(BigStruct {
|
|
||||||
one: 1,
|
|
||||||
two: 2,
|
|
||||||
one_hundred: 100,
|
|
||||||
});
|
|
||||||
|
|
||||||
let y = foo(x);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The idea is that by passing around a box, you're only copying a pointer, rather
|
|
||||||
than the hundred `int`s that make up the `BigStruct`.
|
|
||||||
|
|
||||||
This is an antipattern in Rust. Instead, write this:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(box_syntax)]
|
|
||||||
|
|
||||||
struct BigStruct {
|
|
||||||
one: i32,
|
|
||||||
two: i32,
|
|
||||||
// etc
|
|
||||||
one_hundred: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foo(x: Box<BigStruct>) -> BigStruct {
|
|
||||||
*x
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let x = Box::new(BigStruct {
|
|
||||||
one: 1,
|
|
||||||
two: 2,
|
|
||||||
one_hundred: 100,
|
|
||||||
});
|
|
||||||
|
|
||||||
let y: Box<BigStruct> = box foo(x);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that this uses the `box_syntax` feature gate, so this syntax may change in
|
|
||||||
the future.
|
|
||||||
|
|
||||||
This gives you flexibility without sacrificing performance.
|
|
||||||
|
|
||||||
You may think that this gives us terrible performance: return a value and then
|
|
||||||
immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
|
|
||||||
smarter than that. There is no copy in this code. `main` allocates enough room
|
|
||||||
for the `box`, passes a pointer to that memory into `foo` as `x`, and then
|
|
||||||
`foo` writes the value straight into the `Box<T>`.
|
|
||||||
|
|
||||||
This is important enough that it bears repeating: pointers are not for
|
|
||||||
optimizing returning values from your code. Allow the caller to choose how they
|
|
||||||
want to use your output.
|
|
||||||
|
|
||||||
# Creating your own Pointers
|
# Creating your own Pointers
|
||||||
|
|
||||||
This part is coming soon.
|
This part is coming soon.
|
||||||
|
Loading…
Reference in New Issue
Block a user