Box<T>

Box Ă© um ponteiro owned para dados no heap:

fn main() {
    let five = Box::new(5);
    println!("cinco: {}", *five);
}
5StackHeapfive

Box<T> implementa Deref<Target = T>, o que significa que vocĂȘ pode chamar mĂ©todos de T diretamente em um Box<T>.

Tipos de dados recursivos ou tipos de dados com tamanhos dinĂąmicos precisam usar uma Box:

#[derive(Debug)]
enum List<T> {
    /// Uma lista nĂŁo vazia: primeiro elemento e o resto da lista.
    Element(T, Box<List<T>>),
    /// Uma lista vazia.
    Nil,
}

fn main() {
    let list: List<i32> =
        List::Element(1, Box::new(List::Element(2, Box::new(List::Nil))));
    println!("{list:?}");
}
PilhaHeaplistaElem1Elem2Nil
This slide should take about 8 minutes.
  • Box Ă© parecido com std::unique_ptr em C++, exceto que ele Ă© garantidamente nĂŁo nulo.

  • Uma Box Ă© Ăștil quando vocĂȘ:

    • hĂĄ um tipo cujo tamanho nĂŁo estĂĄ disponĂ­vel em tempo de compilação, mas o compilador Rust precisa saber o tamanho exato.
    • quer transferir o ownership de um grande volume de dados. Ao invĂ©s de copiar grandes volumes de dados na pilha, eles sĂŁo armazenados usando uma Box no heap e apenas o ponteiro Ă© movido.
  • If Box was not used and we attempted to embed a List directly into the List, the compiler would not be able to compute a fixed size for the struct in memory (the List would be of infinite size).

  • Box resolve esse problema, pois tem o mesmo tamanho de um ponteiro normal e apenas aponta para o prĂłximo elemento da List no heap.

  • Remove the Box in the List definition and show the compiler error. We get the message “recursive without indirection”, because for data recursion, we have to use indirection, a Box or reference of some kind, instead of storing the value directly.

Mais para Explorar

Otimização de Nicho

#[derive(Debug)]
enum List<T> {
    Element(T, Box<List<T>>),
    Nil,
}

fn main() {
    let list: List<i32> =
        List::Element(1, Box::new(List::Element(2, Box::new(List::Nil))));
    println!("{list:?}");
}

Uma Box nĂŁo pode estar vazia, portanto o ponteiro Ă© sempre vĂĄlido e nĂŁo nulo (null). Isto permite que o compilador otimize o layout da memĂłria:

PilhaHeaplistaElem.1Elem.2