Is it possible to create a Box<(T, [U])>?

Viewed 457

The question pretty much says it: can I create a boxed tuple (or any struct) that directly contains a slice as one of its fields?

The Vec::into_boxed_slice method works to create Box<[U]>, but I would like to add on some additional data directly in the box alongside the slice.

For example, here is the kind of struct I would like to box up without using Vec into something like Box<(i32,[u8])>:

struct ConsolidateMe {
    data: i32,
    arr: Vec<u8>,
}

impl ConsolidateMe {
    fn new(n: usize) -> Self {
        let mut arr = Vec::with_capacity(n);
        arr.resize(n, 42);
        ConsolidateMe {
            data: 15,
            arr,
        }
    }
}

(In my application, I am creating many structs on the heap, each of which contains a small array and a few other values. The arrays have different sizes, but the size doesn't change after the struct is created. I'd like these to be compactly stored and to avoid extra indirection to the extent possible.)

1 Answers

The slice-dst crate looks like a perfect fit.

Example:

use slice_dst::SliceWithHeader;

#[derive(Debug, Clone)]
struct MyType {
    inner: Box<SliceWithHeader<String, i32>>,
}

impl MyType {
    fn new(value: &str) -> Self {
        let values: Vec<i32> = value.split(" ").map(|s| s.trim().parse().unwrap()).collect();
        Self {
            inner: SliceWithHeader::new(value.into(), values.into_iter()),
        }
    }
}

fn main() {
    println!("{:?}", MyType::new("1 2 3"));
}
Related