Generic fixed length array?

Hi!

I only just discovered you could do <u8; 3>::try_from(&slice)... which makes me ask, can I do something like this?

    fn magic<[u8; T]>(&self) -> Result<[u8; T], E> {
        let bytes = &self.data[0..T];
        <u8; T>::try_from(bytes)
    }

Obviously T is not a type here, it's a value but I've used it as a demo of what I want to achieve. Basically I want to call let v: [u8; 5] = s.magic::<u8; 5>().unwrap().

You are looking for the unstable feature const generics.

2 Likes

This is possible with min_const_generics, which is currently on beta and will be stable in just under six weeks.

use std::convert::TryFrom;
use std::array::TryFromSliceError;

pub struct Foo {
    data: [u8]
}

impl Foo {
    pub fn magic<const N: usize>(&self) -> Result<[u8; N], TryFromSliceError> {
        let bytes = &self.data[0..N];
        <[u8; N]>::try_from(bytes) // bytes.try_into() will also work
    }
}

(Playground)

Note that this uses the data type already being stored, as you'd expect. You can explicitly specify the number of items desired by doing foo.magic::<5>(), or you can let the compiler possibly infer it.

4 Likes

This is amazing. I've been seeing posts about const generics on reddit for a while now without really understanding what it means, and suddenly it is a solution for my problem. Thanks alice and jhpratt!

Arrays is definitely the big one for min_const_generics. Just a little bit longer!