File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -10,7 +10,7 @@ int* foo {
1010 char *c = "xyz"; // 变量c的作用域开始
1111 return &a;
1212} // 变量a和c的作用域结束
13- ````
13+ ```
1414
1515尽管可以编译通过,但这是一段非常糟糕的代码,现实中我相信大家都不会这么去写。变量a和c都是局部变量,函数结束后将局部变量a的地址返回,但局部变量a存在栈中,在离开作用域后,局部变量所申请的栈上内存都会被系统回收,从而造成了** 悬空指针** 的问题。** 这是一个非常典型的内存安全问题。很多编程语言都存在类似这样的内存安全问题** 。再来看变量c,c的值是常量字符串,存储于常量区,可能这个函数我们只调用了一次,我们可能不再想使用这个字符串,但"xyz"只有当整个程序结束后系统才能回收这片内存,这点让程序员是不是也很无奈?
1616> 备注:对于"xyz",可根据实际情况,通过堆的方式,手动管理(申请和释放)内存。
@@ -182,6 +182,7 @@ pub trait Copy: Clone { }
182182** 哪些情况下我们自定义的类型(如某个Struct等)可以实现Copy特性?**
183183只要这种类型的属性类型都实现了Copy特性,那么这个类型就可以实现Copy特性。
184184例如:
185+
185186``` rust
186187struct Foo { // 可实现Copy特性
187188 a : i32 ,
@@ -198,38 +199,41 @@ struct Bar { //不可实现Copy特性
198199** 那么我们如何来实现Copy特性呢?**
199200有两种方式可以实现。
2002011 . ** 通过derive让Rust编译器自动实现**
202+
201203``` rust
202204#derive (Copy , Clone )]
203205struct Foo {
204206 a : i32 ,
205207 b : bool ,
206208}
207- ```
209+ ```
210+
208211编译器会自动检查Foo的所有属性是否实现了Copy特性,一旦检查通过,便会为Foo自动实现Copy特性。
212+
2092132 . ** 自己实现Clone和Copy trait**
214+
210215``` rust
211216#[derive(Debug )]
212217struct Foo {
213218 a : i32 ,
214219 b : bool ,
215220}
216-
217221impl Copy for Foo {}
218222impl Clone for Foo {
219223 fn clone (& self ) -> Foo {
220224 Foo {a : self . a, b : self . b}
221225 }
222226}
223-
224227fn main () {
225228 let x = Foo { a : 100 , b : true };
226229 let mut y = x ;
227230 y . b = false ;
228-
231+
229232 println! (" {:?}" , x ); // 打印:Foo { a: 100, b: true }
230233 println! (" {:?}" , y ); // 打印:Foo { a: 100, b: false }
231234}
232- ```
235+ ```
236+
233237从结果我们发现let mut y = x后,x并没有因为所有权move而出现不可访问错误。
234238因为Foo继承了Copy特性和Clone特性,所以我们均需要手动实现这两个特性。
235239
Original file line number Diff line number Diff line change 1- ** 13.2 引用&借用(References&Borrowing) **
1+ ** 引用&借用(References&Borrowing**
22-------------
33
44如上所示,Owership让我们改变一个变量的值变得“复杂”,那能否像其他编程语言那样随意改变变量的值呢?答案是有的。
Original file line number Diff line number Diff line change 1- ** 13.3 生命周期(Lifetimes)**
1+ ** 生命周期(Lifetimes)**
22-------------
33生命周期可以通俗地理解为保证A的依赖B,比A活的更长。这样就可以保证不会悬空指针的问题,保证内存的安全。
44
You can’t perform that action at this time.
0 commit comments