I have an algorithm which utilises arrays of u32. It would be good to parameterise this size. Since the algorithm works with any size of array as long as the sizes in one operation are all identical.
Yes, you can provide a const generic in the generic parameter list of the struct or similar and then use it for associated functions/methods and the types of fields.
I am learning Rust in my normal fashion - by writing code. I find this easier than learning the manual - but it does mean I have to ask random, poorly phrased questions. So my gratitude for the help.
Coming from a long-time OO perspective I have found Rust both confusing and refreshing. My algorithm certainly runs faster now!
Yeah, I learned this way too: unfortunately this can lead you to run directly face-first into all the pointy bits of the language over and over!
The one thing I wish I got told earlier is that if I'm having trouble getting something working, either it taking more code than I think it should or something like continually running into a borrow check error no matter how I rearrange things, that I should probably ask here if there's a better option.
Since you're already here, the best I've got is don't forget about crates (lib.rs is a great way to find them), use clippy, and don't try to put a lifetime parameter in your state.
Thanks, that worked. However, I suspect there may be a problem lurking here that I will need to solve.
While preparing the data to create an instance of the parameterised class I need to call a function that relies on the value of LEN. Something like this:
struct Foo<const LEN: usize> {
arr: [i32; LEN]
}
impl<const LEN: usize> Foo<LEN> {
pub fn new() -> Self {
let arr: [i32; LEN] = create_array([0; LEN])
Self {
arr
}
}
pub fn replace(&mut self, arr: [i32; LEN]) {
self.arr = arr;
}
fn create_array(src: [i32; LEN]) -> [i32; LEN] {
(0 .. LEN).map(| i | {
i * 2
})
}
}
fn main() {
let mut a = Foo::new();
// a.replace([1, 2, 3]); // compilation err: expected an array with a size of 2, found one with a size of 3
// let b = Foo::<1>::new([1,2]); // compilation err: expected an array with a size of 1, found one with a size of 2
}
How does the create_array function get the correct value of LEN if I create both a Foo<5> and a Foo<3>?
And if the function is defined outside of the impl block of Foo you need to add the same const generic as for Foo:
fn create_array<const LEN: usize>() -> [i32; LEN] {
const { assert!(LEN <= i32::MAX as usize, "LEN is too large to fit in i32") };
std::array::from_fn(|i| i32::try_from(i).unwrap() * 2)
}
@jendrikw@A1cey Thank you both for that - I can’t say that I fully understand but I will try it! Once I get more familiar with the language I am sure it will ‘click’.
And yes, I have way too many ‘as’ around my code. But it seems I need to keep jumping between types. I will go back and sort them out once I find a good strategy.