]>
Commit | Line | Data |
---|---|---|
74b04a01 | 1 | A variable was used after its contents have been moved elsewhere. |
60c5eb7d XL |
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 | ||
74b04a01 XL |
106 | If 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 |