Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a Vec into an array without copying the elements?

I have a Vec of nontrivial types with a size I am certain of. I need to convert this into fixed size array. Ideally I would like to do this

  1. without copying the data over - I would like to consume the Vec
  2. without preinitializing the array with zero data because that would be a waste of CPU cycles

Question written as code:

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let points = vec![
        Point { x: 1, y: 2 },
        Point { x: 3, y: 4 },
        Point { x: 5, y: 6 },
    ];

    // I would like this to be an array of points
    let array: [Point; 3] = ???;
}

This seems like a trivial issue, however I have not been able to find satisfactory solution in Vec docs, slicing sections of Rust Books or by Googling. Only thing that I found is to first initialize the array with zero data and later copy all elements over from Vec, however this does not satisfy my requirements.

like image 827
Fireant Avatar asked Mar 06 '23 16:03

Fireant


1 Answers

Doing this correctly is exceedingly difficult. The problem lies in properly handling a panic when there's a partially uninitialized array. If the type inside the array implements Drop, then it would access uninitialized memory, causing undefined behavior.

The easiest, safest way is to use arrayvec:

extern crate arrayvec;

use arrayvec::ArrayVec;

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let points = vec![
        Point { x: 1, y: 2 },
        Point { x: 3, y: 4 },
        Point { x: 5, y: 6 },
    ];

    let array: ArrayVec<_> = points.into_iter().collect();
    let array: [Point; 3] = array.into_inner().unwrap();
    println!("{:?}", array);
}

Beware this only works for specific sizes of arrays because Rust does not yet have generic integers. into_inner also has a performance warning you should pay attention to.

See also:

  • What is the proper way to initialize a fixed length array? (especially this answer)

  • Convert vectors to arrays and back, which inadvertently wrote code that worked without copies, but does not explicitly claim it was on purpose

  • How to get a slice as an array in Rust?

  • Is there a good way to convert a Vec<T> to an array?
  • Slice to fixed-size array
like image 198
Shepmaster Avatar answered Apr 13 '23 01:04

Shepmaster