0

My code generally works with arrays of length 303, and I am overall happy to hard-code that number into my code. But for testing purposes, I would like to show the behaviour of some functions on smaller arrays. How do I implement the equivalent of the following pointwise function? Or is this impossible, and I'll just live with using slices and explicitly checking the sizes of each at runtime, instead of relying on the compiler to not let anything slip through?

    pub fn recover<N>(
        mut patch_resources: &[KCal; N],
        patch_max_resources: &[KCal; N],
        resource_recovery: f32,
        accessible_resources: f32)
    where
        N: usize
    {
        for i in N {
            if patch_resources[i] < patch_max_resources[i] {
                let inaccessible = patch_max_resources[i] * (1. - accessible_resources) / accessible_resources;
                let underlying_resources = patch_resources[i] + inaccessible;
                patch_resources[i] += underlying_resources
                    * resource_recovery
                    * (1. - underlying_resources * accessible_resources/ patch_max_resources[i]);
            }
            assert!(patch_resources[i].is_normal());
        }
    }
Anaphory
  • 6,045
  • 4
  • 37
  • 68
  • Does https://stackoverflow.com/questions/52379284/can-i-get-a-rust-arrays-length-with-only-a-type-not-a-concrete-variable/52385654#52385654 answer your question? – Markus Klein Jul 14 '20 at 14:54
  • Seeing as you already take references, would a slice (`&[KCal]`) work? – justinas Jul 14 '20 at 15:13
  • The downside I see with a slice, as mentioned in the question, is that checking N==N becomes a task for runtime, instead of for the compiler. – Anaphory Jul 14 '20 at 15:37
  • @MarkusKlein If “Do it with macros” is better than “do it with slices”, yes. I guess it depends on my use case, which is happy to shave of anything not needed in runtime and needs only two-or-so implementations, so macros (compile time) are better than slices (run time) , so yes? – Anaphory Jul 14 '20 at 15:42

1 Answers1

0

I think you need generic-array crate.

I think your code would be like this

  pub fn recover<N>(
        mut patch_resources: &GenericArray<KCal, N>,
        patch_max_resources: &GenericArray<KCal, N>,
        resource_recovery: f32,
        accessible_resources: f32)
    where
        N: ArrayLength<usize>
    {
        for i in N {
            if patch_resources[i] < patch_max_resources[i] {
                let inaccessible = patch_max_resources[i] * (1. - accessible_resources) / accessible_resources;
                let underlying_resources = patch_resources[i] + inaccessible;
                patch_resources[i] += underlying_resources
                    * resource_recovery
                    * (1. - underlying_resources * accessible_resources/ patch_max_resources[i]);
            }
            assert!(patch_resources[i].is_normal());
        }
    }