Skip to content

Commit 602dd42

Browse files
author
wayslog
committed
bug fixed
1 parent 426f700 commit 602dd42

3 files changed

Lines changed: 12 additions & 8 deletions

File tree

12-ownership-system/12-01-ownership.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff 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
186187
struct Foo { //可实现Copy特性
187188
a: i32,
@@ -198,38 +199,41 @@ struct Bar { //不可实现Copy特性
198199
**那么我们如何来实现Copy特性呢?**
199200
有两种方式可以实现。
200201
1. **通过derive让Rust编译器自动实现**
202+
201203
```rust
202204
#derive(Copy, Clone)]
203205
struct Foo {
204206
a: i32,
205207
b: bool,
206208
}
207-
```
209+
```
210+
208211
编译器会自动检查Foo的所有属性是否实现了Copy特性,一旦检查通过,便会为Foo自动实现Copy特性。
212+
209213
2. **自己实现Clone和Copy trait**
214+
210215
```rust
211216
#[derive(Debug)]
212217
struct Foo {
213218
a: i32,
214219
b: bool,
215220
}
216-
217221
impl Copy for Foo {}
218222
impl Clone for Foo {
219223
fn clone(&self) -> Foo {
220224
Foo{a: self.a, b: self.b}
221225
}
222226
}
223-
224227
fn 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

12-ownership-system/12-02-borrowing_references.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
**13.2 引用&借用(References&Borrowing**
1+
**引用&借用(References&Borrowing**
22
-------------
33

44
如上所示,Owership让我们改变一个变量的值变得“复杂”,那能否像其他编程语言那样随意改变变量的值呢?答案是有的。

12-ownership-system/12-03-lifetimes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
**13.3 生命周期(Lifetimes)**
1+
**生命周期(Lifetimes)**
22
-------------
33
生命周期可以通俗地理解为保证A的依赖B,比A活的更长。这样就可以保证不会悬空指针的问题,保证内存的安全。
44

0 commit comments

Comments
 (0)