I\'m doing something like this:
fn main() {
//[1, 0, 0, 0, 99]; // return [2, 0, 0, 0, 99]
//[2, 3, 0, 3, 99]; // return [2,3,0,6,99]
//[2, 4, 4,
Well, something has to own each of those arrays, because references can't own things. And the arrays are of different sizes, so the owner has to be a pointer. The most common array-like owning pointer is Vec
:
let map: Vec<(Vec<usize>, &[usize])> = vec![
(vec![1, 0, 0, 0, 99], &[2, 0, 0, 0, 99]),
(vec![2, 3, 0, 3, 99], &[2, 3, 0, 6, 99]),
(vec![2, 4, 4, 5, 99, 0], &[2, 4, 4, 5, 99, 9801]),
(vec![1, 1, 1, 4, 99, 5, 6, 0, 99], &[30, 1, 1, 4, 2, 5, 6, 0, 99]),
];
for (mut x, y) in map {
execute_program(&mut x);
assert_eq!(x, y);
}
The arrays are therefore owned by map
and borrowed when necessary, as loganfsmyth also suggested in the question comments.
You may be concerned about the performance cost of making unnecessary allocations. This is the cost of using a single let
; since the arrays are not all the same size, if you want them on the stack there really isn't a way around declaring them with different let
s. However, you could write a macro that removes the boilerplate.
y
?You may wonder why I turned x
into a vector, but left y
as it is. The answer is that because y
is a shared reference, those arrays are subject to static promotion, so that &[2, 0, 0, 0, 99]
is actually of type &'static [usize; 5]
which can be coerced to &'static [usize]
. &mut
references do not trigger static promotion because it is unsafe to mutate a static value without some kind of synchronization.