"Dynamic" sized arrays in closures

Currently my code looks like this
let mut f = File::open(filepath).unwrap();

let mut read_bytes2 =  |mut f:&File|{
    let mut bytes2 = [0u8; 2];
    f.read(&mut bytes2);
    bytes2
};

let  mut read_bytes4 =  |mut f:&File|{
   let mut bytes4 = [0u8; 4];
   f.read(&mut bytes4);
   bytes4
};

 let a = i16::from_le_bytes(read_bytes2(f.borrow_mut()));
 let b = i32::from_ne_bytes(read_bytes4(f.borrow_mut()));

It compiles and works but, basically those two cloures look the same it just the size of the array which is different. Is there an elegant way that I can pass the size of the array into the clousre without running into the error “doesn’t have a size known at compile-time”.

Because obviously, this throws the error above

  let  mut read_bytes =  |mut f:&File, size:u8|{
    let mut bytes4 = [0u8; size];
    f.read(&mut bytes4);
    bytes4
};

 let a = i16::from_le_bytes(read_bytes(f.borrow_mut(), 2));
 let b = i32::from_ne_bytes(read_bytes(f.borrow_mut(), 4));

Any ideas I can do this better?

You can use a macro to do this I think

Specifically:

macro_rules! read_bytes {
    ($f:expr, $n: expr) => ({
        let mut bytes = [0u8; $n];
        $f.read(&mut bytes);
        bytes
    });
    ($f:expr, $n: expr,) => (read_bytes!($f, $n));
}

Const generics would, I think, make this possible using a regular generic function:

fn read_bytes<R: Read, const N: usize>(f: &mut R) -> [u8; N] {
    let mut bytes = [0u8; N];
    f.read(&mut bytes);
    bytes
}
2 Likes

Thanks for your answer.
Currently I’ve not started working with makros but I guess this approach will work.
The generic function approach does not work as const is not supported so far as paramenter of a generich function or a function at all. At least this seems so for me.

Yes, but I only wanted to point out that this will be possible soon (probably). See the link to the RFC in my previous post.

Ah. I 've ignored the link you have posted sorry. In that case I will wait :slight_smile: until the feature is available and keep the code like it is so far.