What is the idiomatic way for index operation?


#1

I am implementing a 2-dimension array on 1-dimension one.
I need many type conversions between usize and isize. The following is a sample code.

const WIDTH: usize = 9;
const NEIGHBORS: [isize; 4] = [-(WIDTH as isize), -1, 1, WIDTH as isize];

fn some_operation(i: usize) -> i32 {
    0 // dummy
}

fn main() {
    let mut a = [0; WIDTH * WIDTH];
    let p = 41usize; // p should be equal to or larger then WIDTH.
    for e in &NEIGHBORS {
        a[(p as isize + e) as usize] = some_operation(p); // maybe I need methods for index operations
    }
}

Is it a correct way? Or are there any simpler coding way?


#2

That looks mostly fine, you might need to change (p as isize + *e) as usize since e is actually a reference.

What I would recommend is changing p to an isize if possible, that gets ride of an extra cast then you could just do: (p +*e) as usize.

Another option would be doing:

fn main() {
    let neighbors = |x| [ x - WIDTH, x - 1, x + 1, x + WIDTH];

    let mut a = [0; WIDTH * WIDTH];
    let p = 41 as usize;

    for e in neighbors(p).iter() {
        a[*e] = some_operation(p);
    }  
}

Not sure if this is faster from a performance point of view (it is using 16(?) bytes of stack) but it is a little easier to read I think.


#3

(It came out that I had never compiled the sample code ^^; )

Actually I used p as direct index for another access, so if you change p as isize, you need cast there.

I like your code very much. I wonder if the closure is inline, your code may be faster than mine because of no cast.

I will experiment it.

Thank you!