2

I need to pass a reference to an array of references to arrays (or slice of slices) to the following function in Rust

const LNGTH: usize = 5;

fn swap_array<T>(x: &mut [&[T; LNGTH]]) {
    let temp = x[1];
    x[1] = x[0];
    x[0] = temp;
}

The problem is that it seems I have to specify an array length for the "inner" arrays (here: LNGTH).

So, the following code works fine:

fn main() {
    let x_array: [i32; LNGTH] = [5,2,8,9,1];
    let x_other: [i32; LNGTH] = [6,7,6,7,6];        
    let mut y_array: [&[i32; LNGTH]; 2] = [&x_array, &x_other];
    println!("before : {:?}", y_array);
    swap_array(&mut y_array);
    println!("after  : {:?}", y_array);    
} 

But if I change the signature of swap_array to fn swap_array<T>(x: &mut [&[T]]), I get the following error:

error[E0308]: mismatched types
  --> src/main.rs:14:16
   |
14 |     swap_array(&mut y_array[..]);
   |                ^^^^^^^^^^^^^^^^ expected slice, found array of 5 elements
   |
   = note: expected type `&mut [&[_]]`
              found type `&mut [&[i32; 5]]`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `tut_arrays`.

From the perspective of C, I would like to have a function that accepts arguments of type T**. A corresponding function in C would look like that

void swap_arrays(my_type ** x) {
    my_type* temp = x[1];
    x[1] = x[0];
    x[0] = temp;
}
4
  • "But if I change the signature of swap_array to fn swap_array<T>(x: &mut [&[T; LNGTH]])" — that's what it already is. Did you mean to say fn swap_array<T>(x: &mut [&[T]])? Commented Nov 26, 2018 at 12:00
  • @PeterHall Thank you for pointing out to this typo. I fixed it now. Commented Nov 26, 2018 at 12:56
  • 1
    Note that in C the situation is similar: a two dimensional array int x[5][10] is not convertible to int** but to int (*)[10]. Commented Nov 26, 2018 at 13:17
  • Thanks, @rodrigo. Your comment is very elucidating! Commented Nov 26, 2018 at 14:24

1 Answer 1

2

Here is a slice-of-slices version:

const LEN: usize = 5;

fn swap_array<T>(x: &mut [&[T]]) {
    let temp = x[1];
    x[1] = x[0];
    x[0] = temp;
}

fn main() {
    let x_array: [i32; LEN] = [5, 2, 8, 9, 1];
    let x_other: [i32; LEN] = [6, 7, 6, 7, 6];
    let mut y_array: [&[i32]; 2] = [&x_array, &x_other];
    println!("before : {:?}", y_array);
    swap_array(&mut y_array);
    println!("after  : {:?}", y_array);
}

You have to change the formal argument to slice of slices, and the elements of y_array must be slices, too (the latter is basically what the error message said).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.