Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take a known number of inputs

Tags:

rust

I am looking to take a known number of inputs in rust. In this case I'm taking in poker hands for problem 54 of project Euler where each line parses into a two hands of five cards each. There are two main approaches I've found to this situation neither of which I like.

Approach 1:

let mut buffer_1 = Vec::with_capacity(5);
for i in 0..5 {
    buffer_1.push(i)
}
assert_eq!(buffer_1.len(), 5);

Approach 2:

let mut buffer_2 = [None, 5];
for i in 0..5 {
    buffer_2[i as usize] = Some(i)
}

Approach 1 is on the heap despite having a known size at compile time and approach 2 gives me a optional values where I know everything is a Some. What I would ideally like is something capable of collecting some function or colsure into an array or similar. e.g.

fn array_from_colsure<T>(length: usize, closure: fn() -> T) -> Option<[T; length]> {
    // implementation
}
#[test]
fn array_from_closure_test() {
    let a: [i32; 5] = array_from_colsure(5, || {for i in 0..5 {i}}).unwrap()
}

Clarification: I am looking to find something with this functionality not create it from scratch.

As Silvio Mayolo's excellent answer shows (I have edited the desired functionality slightly since the original question), implementing my suggestion will require a horrific amount of unsafe code (not to mention an awful lot of effort for such a small optimisation). So it is not sensible to do it for a small number of projects.

like image 870
Pioneer_11 Avatar asked Dec 11 '25 16:12

Pioneer_11


1 Answers

You can use std::array::from_fn:

let buffer: [i32; 5] = std::array::from_fn(|i| i as i32);

I also offer up ArrayVec from either the arrayvec or tinyvec crates which would look like your first approach but wouldn't use a heap allocation.

like image 87
kmdreko Avatar answered Dec 14 '25 12:12

kmdreko