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