Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function to build a fixed sized array from slice [duplicate]

Tags:

rust

Related: Slice to fixed-size array, however I am looking for a more specific form.

Ideally, I would want to build a function with the following signature:

fn make_array<T; N>(slice: &[T]) -> [T; N];

since this is not possible yet (since non-type parameters are not a thing), I instead thought of having the function directly take in the array:

fn make_array<A>(slice: &[T]) -> A;

where one would substitute [T; N] for A.

Here is, so far, my most promising attempt:

use std::ops::DerefMut;

fn make_array<A, T>(slice: &[T]) -> A
    where A: Sized + Default + DerefMut<Target = [T]>
{
    let mut a = Default::default();
    (&mut a[..]).copy_from_slice(slice);
    a
}

fn main() {
    let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    let a: [u8; 4] = make_array(&original[0..4]);

    println!("{:?}", a);
}

However I am missing the trait that allows an array to be coerced to a slice (hint: it's not DerefMut).

As long as I am okay for the function to only work for small arrays, is there a way to build such a function using safe code?

like image 875
Matthieu M. Avatar asked Dec 08 '25 14:12

Matthieu M.


1 Answers

AsMut (or BorrowMut) works:

use std::convert::AsMut;

fn make_array<A, T>(slice: &[T]) -> A
    where A: Sized + Default + AsMut<[T]>,
          T: Copy
{
    let mut a = Default::default();
    // the type cannot be inferred!
    // a.as_mut().copy_from_slice(slice);
    <A as AsMut<[T]>>::as_mut(&mut a).copy_from_slice(slice);
    a
}
like image 184
malbarbo Avatar answered Dec 12 '25 10:12

malbarbo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!