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}