fn add1(x: Thing) -> Thing {
x + 1
}
fn add2(x: &Thing) -> Thing {
x + 2
}
This works on the assumption that whatever "+ 1" really means doesn't itself need ownership of x, e.g. because it mutates it. If it does, then you'll get an error. Or you could do this: fn add3(x: &mut Thing) {
x.add(3)
}
Which, presumably, modifies x instead of returning a copy. It's your job to make sure it makes sense to do that, but Rust has another trick in its pockets: let y = add1(x); // Works; takes ownership.
let z = add2(&y); // Works, and doesn't take ownership.
let zz = add2(&y); // So you can do it twice. (Y tho?)
let h = add3(&y); // Compile-time error!
let hh = add3(&mut y); // Works. You need to specify that you're fine with y being mutated. fn add1(x: Vec<i32>) -> Vec<i32> { // Takes ownership
return x.iter().map(|&x| x + 1).collect::<Vec<_>>();
}
fn add1_borrow(x: &Vec<i32>) -> Vec<i32> {
return x.iter().map(|&x| x + 1).collect::<Vec<_>>();
}
The first will take ownership of the thing you pass in, so you can't do something like this: let x = vec![1, 2, 3];
let y = add1(x);
let z = add1(x); // error[E0382]: use of moved value: `x`
but the follow code is OK, because the function just borrows the value instead of owning (and destroying) it: let x = vec![1, 2, 3];
let y = add1_borrow(&x);
let z = add1_borrow(&x);
This is legal too: let x = vec![1, 2, 3];
let y = add1_borrow(&x);
let z = add1(x);
but as before you can't use x after this.(Note, I chose Vec here because Vec does not implement Copy: if I used i32 it would just copy the value in the non-borrowing case, which would make the code fine as no ownership would be transferred.)