mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-29 14:36:22 +00:00
86 lines
1.9 KiB
Markdown
86 lines
1.9 KiB
Markdown
|
---
|
|||
|
id: d20e0dd7-ac1d-4dbb-b4e7-a6780b77bd69
|
|||
|
title: Box\<T\>
|
|||
|
---
|
|||
|
|
|||
|
# Introduction
|
|||
|
|
|||
|
Boxes allow you to store data on the heap rather than the stack. What
|
|||
|
remains on the stack is the pointer to the heap data.
|
|||
|
|
|||
|
Boxes don’t have performance overhead, other than storing their data on
|
|||
|
the heap instead of on the stack. But they don’t have many extra
|
|||
|
capabilities either. There are three typical user cases for Boxes:
|
|||
|
|
|||
|
- When you have a type whose size can’t be known at compile time and
|
|||
|
you want to use a value of that type in a context that requires an
|
|||
|
exact size
|
|||
|
- When you have a large amount of data and you want to transfer
|
|||
|
ownership but ensure the data won’t be copied when you do so
|
|||
|
- When you want to own a value and you care only that it’s a type that
|
|||
|
implements a particular trait rather than being of a specific type
|
|||
|
|
|||
|
``` rust
|
|||
|
fn main() {
|
|||
|
let b = Box::new(5);
|
|||
|
println!("b = {}", b);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
# Reason to choose Box\<T\>
|
|||
|
|
|||
|
`Box<T>` allows immutable or mutable borrows checked at compile time;
|
|||
|
[Rc\<T\>](20200929145534-rc_t) allows only immutable borrows checked at
|
|||
|
compile time; [RefCell\<T\>](20200929152628-refcell_t) allows immutable
|
|||
|
or mutable borrows checked at runtime.
|
|||
|
|
|||
|
# Usercases
|
|||
|
|
|||
|
## Type whose size can't be known at compile time
|
|||
|
|
|||
|
When you have a type whose size can’t be known at compile time and you
|
|||
|
want to use a value of that type in a context that requires an exact
|
|||
|
size.
|
|||
|
|
|||
|
The following won't compile as the `List` type doesn't have a known
|
|||
|
size:
|
|||
|
|
|||
|
``` rust
|
|||
|
enum List {
|
|||
|
Cons(i32, List),
|
|||
|
Nil,
|
|||
|
}
|
|||
|
|
|||
|
fn main() {}
|
|||
|
```
|
|||
|
|
|||
|
This won't fly either:
|
|||
|
|
|||
|
``` rust
|
|||
|
enum List {
|
|||
|
Cons(i32, List),
|
|||
|
Nil,
|
|||
|
}
|
|||
|
|
|||
|
use crate::List::{Cons, Nil};
|
|||
|
|
|||
|
fn main() {
|
|||
|
let list = Cons(1, Cons(2, Cons(3, Nil)));
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
With pointers all things are possible, huzzah:
|
|||
|
|
|||
|
``` rust
|
|||
|
enum List {
|
|||
|
Cons(i32, Box<List>),
|
|||
|
Nil,
|
|||
|
}
|
|||
|
|
|||
|
use crate::List::{Cons, Nil};
|
|||
|
|
|||
|
fn main() {
|
|||
|
let _list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
|
|||
|
}
|
|||
|
```
|