1

I'm currently learning Rust and I was experimenting about vectors, and as it's mentioned in the documentation, the signature of the push method of the Vect module is as follows:

pub fn push(&mut self, value: T)

From the above, we can see that the push method takes the variable itself and not a reference to the variable named "value" (obviously) and thus it takes ownership of it and therefor after using the push method it's no longer feasible to use the value passed in the parameter. But it turns that it's possible to use it, after I've compiled and executed the following snippet

let mut v = vec![1, 2, 3, 4, 5];
let mut x = 10;
v.push(x);
println!("{:?}", v);
x = 20;
println!("{}", x);
println!("{:?}", v);

I got no compile or run time error whatsoever, and I'd really like to know why so, because it's ether my understanding of the signature is messed up or there is something that i don't know and I'd like to.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kami SM
  • 29
  • 6

2 Answers2

4

push() does take ownership, but integers are Copy, meaning they cannot be moved, only copied. And after they are copied the original value can still be used. Try pushing a String.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • That make sense now, after trying it on `String` and seeing this question stackoverflow.com/a/70833686/5397009 mentioned in the comments above ig what causes this behavior is the implementation of borrowing/copying values for a primitive type as for a=b a and b will have each it's own scope with it's own value. Appreciated for your help. – Kami SM May 23 '23 at 06:49
  • To be precise "types which are `Copy` cannot be moved" is an overstatement. Compiler can do whatever it wants. So values which are `Copy` have *copy semantics*, but if they are not used after such copy compiler can as well move them if it pleases it. – Aleksander Krauze May 23 '23 at 07:56
  • @AleksanderKrauze This is a meaningless distinction, since both move and copy are memcpy. – Chayim Friedman May 23 '23 at 12:09
1

From "Programming Rust (Revised 2nd Edition)", Chapter 4: Ownership and Moves, p.94-95:

Copy Types: The Exception to Moves
...
...
Assigning a value of a Copy type copies the value, rather than moving it. The source of the assignment remains initialized and usable, with the same value it had before. Passing Copy types to functions and constructors behaves similarly.

The standard Copy types include all the machine integer and floating-point numeric types, the char and bool types, and a few others. A tuple or fixed size array of Copy types is itself a Copy type.

An example of the last line:

let x = [2, 4, 6];
let y = x;
println!("From x: {}", x[0]);
println!("From y: {}", y[0]);

--output:--
From x: 2
From y: 2
7stud
  • 46,922
  • 14
  • 101
  • 127