What does '&' before an argument binding mean?


#1

These two examples appear to do the same thing:

fn foo(&x : &i32) -> i32 { x + 1 }
foo(&2);
fn bar(x : &i32) -> i32 { x + 1 }
bar(&2);

I couldn’t see anything in the reference manual. Does it do anything?


#2

It’s an irrefutable pattern. In this case, it destructures the &i32 into the & part and the i32 part and binds the i32 part to x.

It’s equivalent to:

fn foo(x : &i32) -> i32 {
    let &y: i32 = x;
    y + 1
}

Or

fn foo(x : &i32) -> i32 {
    let y: i32 = *x;
    y + 1
}

As you noticed in bar, this isn’t really necessary in this case because the Add operator is implemented on both &i32 and i32.

Another example of an irrefutable pattern (destructuring a tuple):

fn baz((a, b) : (i32, i32), c: i32) -> i32 {
   a + b + c
}
baz((1, 2), 3);

#3

Thanks! That makes perfect sense.


#4

@stebalien The first foo function doesn’t compile: the let &y: i32 = x should be let &y: &i32 = x.


#5

Thanks for catching that. I guess : type annotates the pattern not the binding.