study_example/ownership/ownership.rs
1pub mod ownership_test {
2 fn var_scope_study() {
3 // 这里因为s没有定义所以是非法的
4 {
5 let s = "hello"; // s从这里开始变得有效
6 println!("s {s}");
7 }
8 // 离开了上面的scope,s已经失效
9 /*
10 error[E0425]: cannot find value `s` in this scope
11 --> src/ownership/ownership.rs:9:22
12 |
13 9 | println!("s {s}");
14 | ^ not found in this scope*/
15 // println!("s {s}");
16 }
17
18 fn string_type_owner_study() {
19 // 双冒号 :: 运算符允许我们在 String 命名空间这个类型下的特定的 from 函数
20 // 这句会请求需要的内存分配;
21 {
22 let mut s = String::from("hello");
23 /*
24 * String比起文本可以动态的原因:
25 */
26 s.push_str(" rust");
27 println!("s: {s}");
28 }
29 // 离开scope调用drop,释放内存;
30 }
31
32 fn string_mul_to_one_var_study() {
33 let mut s1 = String::from("hello");
34 let s2 = s1;
35 let mut s3 = s2.clone();
36 s3.push_str(" rust");
37 println!("s2 {} s3 {}", s2, s3);
38 /*
39 error[E0382]: borrow of moved value: `s1`
40 --> src/ownership/ownership.rs:35:23
41 |
42 33 | let mut s1 = String::from("hello");
43 | ------ move occurs because `s1` has type `String`, which does not implement the `Copy` trait
44 34 | let s2 = s1;
45 | -- value moved here
46 35 | println!("s1: {s1}");
47 | ^^^^ value borrowed here after move
48 */
49 // println!("s1: {s1}");
50 let x: u16 = 88;
51 let y = x;
52 println!("x = {} y = {}", x, y);
53 // 如果在不同的scope下呢
54 {
55 let mut s4 = s3;
56 println!("s4 {s4}");
57 }
58 // value borrowed here after move
59 // println!("{s3}");
60 }
61
62 fn take_ownership(str: String) {
63 println!("str {} take_ownership", str);
64 }
65 fn makes_copy(int: i32) {
66 println!("int {}", int);
67 }
68 fn move_function_study() {
69 let mut str = String::from("move_function_study hello");
70 take_ownership(str);
71 // str value borrowed here
72 // println!("{str}");
73 let mut int1 = 188;
74 makes_copy(int1);
75 println!("move_function_study int1 {int1}");
76 }
77
78 fn gives_ownership() -> String {
79 let str = String::from("gives_ownership");
80 str
81 }
82 fn takes_and_gives_ownership(a_string: String) -> String {
83 a_string // a_string is returned and moves out to the calling function
84 }
85 fn caculate_length(str: String) -> (String, usize) {
86 let length = str.len();
87 (str, length)
88 }
89 fn move_function_ownership_study_2() {
90 let str_from_gives_ownership = gives_ownership();
91 println!("{str_from_gives_ownership}");
92 let str_from_takes_and_gives = takes_and_gives_ownership(str_from_gives_ownership);
93 println!("{str_from_takes_and_gives}");
94 let (str_ret, str_ret_len) = caculate_length(str_from_takes_and_gives);
95 println!("{str_ret} length {str_ret_len}");
96 }
97
98 pub fn ownership_test_handle() {
99 println!("ownership test handle.");
100 var_scope_study();
101 string_type_owner_study();
102 string_mul_to_one_var_study();
103 move_function_study();
104 move_function_ownership_study_2();
105 }
106}
107
108pub mod reference_borrow {
109
110 fn caculate_length(str_ref: &String) -> usize {
111 str_ref.len()
112 }
113 // 如果引用的数据要更新如何处理
114 /*
115 error[E0596]: cannot borrow `*str_ref` as mutable, as it is behind a `&` reference
116 --> src/ownership/ownership.rs:115:9
117 |
118 115 | str_ref.push_str(" modify str");
119 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `str_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
120 */
121 fn modify_str(str_ref: &String) {
122 // str_ref.push_str(" modify str");
123 }
124 // 上述方法解决如下
125 fn modify_str_correct(str_ref: &mut String) {
126 str_ref.push_str(" modify str");
127 }
128 fn reference_study() {
129 let mut str = String::from("reference_borrow->reference_study hello");
130 let len = caculate_length(&str);
131 // str 离开了caculate_length的scope,但是str依然能使用;
132 println!("str after call: {str}, len = {len}");
133 modify_str_correct(&mut str);
134 println!("str after modify_str_correct(str_ref: &mut String): {str}");
135 }
136 fn reference_mutable_study() {
137 let mut str = String::from("reference_borrow->reference_mutable_study hello");
138 let ref1 = &mut str;
139 /*
140 error[E0499]: cannot borrow `str` as mutable more than once at a time
141 --> src/ownership/ownership.rs:139:20
142 |
143 138 | let ref1 = &mut str;
144 | -------- first mutable borrow occurs here
145 139 | let ref2 = &mut str;
146 | ^^^^^^^^ second mutable borrow occurs here
147 */
148 // let ref2 = &mut str;
149 println!("ref1 {ref1}"); // ref1 reference_borrow->reference_mutable_study hello
150 // println!("ref2 {ref2}");
151 // 解决办法如下
152 {
153 let ref2 = &mut str;
154 println!("ref2 {ref2}");
155 }
156 }
157 fn reference_mutable_immutable_study() {
158 let mut str = String::from("reference_borrow->reference_mutable_study hello");
159 let ref1 = &str;
160 let ref2 = &str;
161 // error[E0502]: cannot borrow `str` as mutable because it is also borrowed as immutable
162 // let ref3 = &mut str;
163 println!("ref1: {}, ref2: {}", ref1, ref2);
164 // 引用的范围从引入它的地方开始,一直持续到上次使用该引用时为止,所以因为前面是最后一次使用两个不变引用,这里可以正常定义可变引用;
165 let ref3 = &mut str;
166 println!("ref3: {ref3}");
167 }
168
169 /*
170 error[E0106]: missing lifetime specifier
171 --> src/ownership/ownership.rs:169:36
172 |
173 169 | fn dangle_reference_study() -> &String {
174 | ^ expected named lifetime parameter
175 */
176 /*fn dangle_reference_study() -> &String { // returns a reference to a String
177 let str = String::from("dangle hello."); // 创建一个字符串
178 &str 返回字符串的引用
179 }*/
180 //离开scope,drop了,内存释放了,引用就dangle了;
181
182 pub fn reference_borrow_study() {
183 reference_study();
184 reference_mutable_study();
185 reference_mutable_immutable_study();
186 }
187}
188
189pub mod slice {
190 fn find_first_word_end_index(source_str: &String) -> usize {
191 let bytes = source_str.as_bytes(); // 转换为byte的slice用于遍历
192 // 首先使用 iter 方法在字节数组上创建一个迭代器
193 // enumerate 包装 iter 的结果并将每个元素作为集合的一部分返回。元组代替。
194 // 从 enumerate 返回的元组的第一个元素是索引,第二个元素是对该元素的引用
195 for (i, &item) in bytes.iter().enumerate() {
196 if item == b' ' {
197 return i;
198 }
199 }
200 return source_str.len();
201 }
202
203 // 字符串的切片表示为&str
204 fn find_first_word(source_str: &String) -> &str {
205 let index = find_first_word_end_index(source_str);
206 // slice的start_index和end_index,end_index比元素大1;0和源字符串的末尾的index可以省略
207 return &source_str[..index];
208 }
209
210 fn find_first_word_from_slice(str: &str) -> &str {
211 let bytes = str.as_bytes();
212 let mut index = str.len();
213 for (i, &item) in bytes.iter().enumerate() {
214 if item == b' ' {
215 index = i;
216 }
217 }
218 return &str[..index];
219 }
220
221 fn string_literal_slice() {
222 // 这里的string_literal的类型是&str(字符串切片),这是之乡二进制文件的切片,也是字符串文件不可变的原因;
223 let string_literal = "hello string literal";
224 }
225
226 fn array_slice() {
227 let a: [u32; 5] = [28, 34, 52, 43, 75];
228 let slice = &a[1..3];
229 assert_eq!(slice, &[34, 52]);
230 }
231
232 pub fn slice_study() {
233 let mut source_str = String::from("slice hello");
234 let index = find_first_word_end_index(&source_str);
235 let first_word = find_first_word(&source_str);
236 println!("first word end index {index}");
237 // error[E0502]: cannot borrow `source_str` as mutable because it is also borrowed as immutable
238 // source_str.clear();
239 println!("frist word: {first_word}");
240 string_literal_slice();
241 let fist_slice = find_first_word_from_slice(&source_str[2..8]);
242 println!("frist slice: {fist_slice}");
243 array_slice();
244 }
245}