wiki/content/20200929135609-box_t.md

87 lines
2 KiB
Markdown
Raw Normal View History

2024-05-06 20:40:05 +00:00
---
2024-10-29 18:27:12 +00:00
date: 2020-09-29
2024-05-06 20:40:05 +00:00
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 dont have performance overhead, other than storing their data on
the heap instead of on the stack. But they dont have many extra
capabilities either. There are three typical user cases for Boxes:
- When you have a type whose size cant 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 wont be copied when you do so
- When you want to own a value and you care only that its 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 cant 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))))));
}
```