Hi,all
Why doesn't the compiler issue an error at Line 15 while I am trying to assign it's field with a new value ? It did throw a message at Line 16 saying p was moved at Line 14 already.
Hi,all
Why doesn't the compiler issue an error at Line 15 while I am trying to assign it's field with a new value ? It did throw a message at Line 16 saying p was moved at Line 14 already.
Hi,
This section in the documentation is describing what is happening What is Ownership? - The Rust Programming Language
Also a small hint. You can post code here without using screenshots by writing the code within these blocks
```
Code goes here
```
Cheers
In this section, The Book also states that :
If we tried to use s after the call to takes_ownership, Rust would throw a compile time error.
I wander that why the compiler complains at Line 16 , not Line 15. Both use the moved variable p. I reassign p's field x at Line 15 and the compiler doesn't give a warning or an error. For the user's perspective, Line 15 is useless if so. My question is: what does the compiler do when it comes to Line 15 ?
The line 15 is a partial initialization. (Failing to find a doc link.) It isn't used very often.
I think you can use the following mental model: moving is essentially memcpy
-ing the struct to the called function stack. (usually it's optimized out, but initially it's there) Memory region of old p
is still there on stack, but is marked as "moved", which makes it unreadable, but it does not forbid you from writing into that memory. Same story applies to this example:
let mut p: Point;
// works
p.x = 5;
// compilation error
println!("{}", p.x)
The only difference is that memory region of p
marked not as "moved", but as "uninitialized". Although I agree that your example is strange and ideally Rust should produce error for line 15 as well. (of course if I am not missing some obscure cases where such behaviour will be useful)
I have no idea what the use cases are; but IIRC if you assign all of the fields in this manner, Rust will consider the object to be fully initialized.
Just watch out for the terrifying soundness hole. (surprise, a feature that almost nobody uses has bugs!)
Nope, it does not work like this unfortunately. It could be a nice (but arguably rarely needed) feature if Rust could've tracked partial initialization and detect if type became fully initialized.