silk.mem.box.
One owned value on the heap, for recursive data and for values that must have a fixed-size handle.
When to use#
Use Box when a type must contain itself, such as a tree node that owns child nodes. A field
of type Box<Node> has a fixed size, so the compiler can lay out Node. Use make to
allocate, get or getMut to borrow the value, and into to get the value back.
Details#
A box owns one allocation and one value. get and getMut return a slice of length 1,
because a Silk function cannot return a bare borrowed value. Dropping a box drops its value and
releases the allocation. into moves the value out and releases the allocation one time.
Gotchas#
Dropping a chain of boxes uses one stack frame for each link. For a very long chain, take the
links apart with into in a loop.
Examples#
Store and recover one owned value#
import silk.mem.box { Box }
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }
pub effect fn main() -> i32
! OutOfMemoryError {
let mut allocator = Allocator.systemAllocatorProvider()
let mut boxed = run Box<i32>.make(40) |> Effect.provideMut<Allocator>(&mut allocator)
let mut slot = Box<i32>.getMut(&mut boxed)
slot[0] = slot[0] + 2
drop slot
let value = Box<i32>.into(move boxed)
if value != 42 {
return 1
}
return 0
}Import as Box with import silk.mem.box { Box }.
Public declarations: 3.
Vacant#
pub struct VacantThe state marker of a Box whose value into has moved out. User code does not use it.
Occupied#
pub struct OccupiedThe state marker of a Box that owns its value. User code does not use it.
Box#
pub struct Box<T>An owner of one heap-allocated value of type T.
When to use#
Use a box when a type must contain itself, such as a tree node that owns child nodes. A field
of type Box<Node> has a fixed size, so the compiler can lay out Node. Use make to
allocate, get or getMut to borrow the value, and into to get the value back.
Details#
The size of Box<T> does not depend on T, so a type can contain a box of itself. Dropping a
box drops the value and then releases the allocation. A box is affine. It is not Copy.
Gotchas#
Dropping a chain of boxes uses one stack frame for each link. For a very long chain, take the
links apart with into in a loop.
Implementation Box<T>#
impl<T> Box<T>Associated function make#
pub effect<'env> fn make<'env>(value: T) -> Box<T> ! OutOfMemoryError ? &mut AllocatorAllocates space for one T, moves value into it, and returns the box.
Details#
The allocation comes from the active Allocator. The box owns the value and the allocation.
Errors#
OutOfMemoryErrorif theAllocatorcannot supply the memory. No box is made, andvalueis dropped.
Method get#
pub fn get(self: &Self) -> &[T]Returns a shared borrow of the value, as a slice of length 1.
Details#
Read the value as slice[0]. The slice borrows the box. The box cannot change or move while
the slice is live.
Method getMut#
pub fn getMut(self: &mut Self) -> &mut [T]Returns an exclusive borrow of the value, as a slice of length 1.
Details#
Change the value through slice[0]. The slice borrows the box exclusively. No other use of
the box is possible while the slice is live. Drop the slice to end the borrow early.
Method into#
pub fn into(self: Self) -> TMoves the value out of the box, releases the allocation, and returns the value.
When to use#
Use into when the caller needs the value itself, not a borrow. Use it in a loop to take
apart a long chain of boxes without deep recursion. A plain drop of such a chain uses one
stack frame for each link.
Implementation Drop for Box<T>#
impl<T> Drop for Box<T>Operation drop#
fn drop(self: &mut Box<T>) -> ()Category: Memory.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.