Search code examples
arraysrustvectorborrow-checker

Why does an array require a reference, but a vector doesn't when we pass them as a parameter to a function?


fn _print_array(arr: &[i32])
{
    println!("Array : {:?}", arr);
}

pub fn print_array()
{
    let _a:[i32;3]=[1,2,3];
    _print_array(&_a);
}

fn _print_vector(v: Vec<i32>)
{
    println!("Vector : {:?}", v);
}

pub fn print_vector()
{
    let _v:Vec<i32> = vec![1, 2, 3];
    _print_vector(_v);
}

Why does an array require a reference, but a vector doesn't when we pass them as a parameter to a function?


Solution

  • [i32] is not an array, it's a slice. Slices are unsized, and therefore you can't pass them as function parameters. You can pass arrays.

    fn print_actual_array<const LEN: usize>(arr: [i32; LEN]) {
        println!("Array : {:?}", arr);
    }
    

    You can pass unsized types using a pointer type, such as references (&), Box, or raw pointers (*const). Vec holds a *const pointer to a slice.

    When you do this

    let _a: [i32; 3] = [1, 2, 3];
    _print_array(&_a);
    

    you're actually coercing the array into a slice (similar to Deref or as) which looks like this explicitly

    let _a: [i32; 3] = [1, 2, 3]
    let _b: &[i32] = &_a;
    _print_array(_b);