]> git.proxmox.com Git - rustc.git/blame - src/librustc_error_codes/error_codes/E0382.md
New upstream version 1.47.0+dfsg1
[rustc.git] / src / librustc_error_codes / error_codes / E0382.md
CommitLineData
74b04a01 1A variable was used after its contents have been moved elsewhere.
60c5eb7d
XL
2
3Erroneous code example:
4
5```compile_fail,E0382
6struct MyStruct { s: u32 }
7
8fn main() {
9 let mut x = MyStruct{ s: 5u32 };
10 let y = x;
11 x.s = 6;
12 println!("{}", x.s);
13}
14```
15
16Since `MyStruct` is a type that is not marked `Copy`, the data gets moved out
17of `x` when we set `y`. This is fundamental to Rust's ownership system: outside
18of workarounds like `Rc`, a value cannot be owned by more than one variable.
19
20Sometimes we don't need to move the value. Using a reference, we can let another
21function borrow the value without changing its ownership. In the example below,
22we don't actually have to move our string to `calculate_length`, we can give it
23a reference to it with `&` instead.
24
25```
26fn main() {
27 let s1 = String::from("hello");
28
29 let len = calculate_length(&s1);
30
31 println!("The length of '{}' is {}.", s1, len);
32}
33
34fn calculate_length(s: &String) -> usize {
35 s.len()
36}
37```
38
39A mutable reference can be created with `&mut`.
40
41Sometimes we don't want a reference, but a duplicate. All types marked `Clone`
42can be duplicated by calling `.clone()`. Subsequent changes to a clone do not
43affect the original variable.
44
45Most types in the standard library are marked `Clone`. The example below
46demonstrates using `clone()` on a string. `s1` is first set to "many", and then
47copied to `s2`. Then the first character of `s1` is removed, without affecting
48`s2`. "any many" is printed to the console.
49
50```
51fn main() {
52 let mut s1 = String::from("many");
53 let s2 = s1.clone();
54 s1.remove(0);
55 println!("{} {}", s1, s2);
56}
57```
58
59If we control the definition of a type, we can implement `Clone` on it ourselves
60with `#[derive(Clone)]`.
61
62Some types have no ownership semantics at all and are trivial to duplicate. An
63example is `i32` and the other number types. We don't have to call `.clone()` to
64clone them, because they are marked `Copy` in addition to `Clone`. Implicit
65cloning is more convenient in this case. We can mark our own types `Copy` if
66all their members also are marked `Copy`.
67
68In the example below, we implement a `Point` type. Because it only stores two
69integers, we opt-out of ownership semantics with `Copy`. Then we can
70`let p2 = p1` without `p1` being moved.
71
72```
73#[derive(Copy, Clone)]
74struct Point { x: i32, y: i32 }
75
76fn main() {
77 let mut p1 = Point{ x: -1, y: 2 };
78 let p2 = p1;
79 p1.x = 1;
80 println!("p1: {}, {}", p1.x, p1.y);
81 println!("p2: {}, {}", p2.x, p2.y);
82}
83```
84
85Alternatively, if we don't control the struct's definition, or mutable shared
86ownership is truly required, we can use `Rc` and `RefCell`:
87
88```
89use std::cell::RefCell;
90use std::rc::Rc;
91
92struct MyStruct { s: u32 }
93
94fn main() {
95 let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));
96 let y = x.clone();
97 x.borrow_mut().s = 6;
98 println!("{}", x.borrow().s);
99}
100```
101
102With this approach, x and y share ownership of the data via the `Rc` (reference
103count type). `RefCell` essentially performs runtime borrow checking: ensuring
104that at most one writer or multiple readers can access the data at any one time.
105
74b04a01
XL
106If you wish to learn more about ownership in Rust, start with the
107[Understanding Ownership][understanding-ownership] chapter in the Book.
60c5eb7d 108
74b04a01 109[understanding-ownership]: https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html