|
|
@ -1,16 +1,39 @@
|
|
|
|
# Deref 解引用
|
|
|
|
# Deref 解引用
|
|
|
|
|
|
|
|
在开始之前,我们先来看一段代码:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
|
|
|
struct Person {
|
|
|
|
|
|
|
|
name: String,
|
|
|
|
|
|
|
|
age: u8
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
何为智能指针?能不让你写出 ******s 形式的解引用,我认为就是智能: ),智能指针的名称来源,主要就在于它实现了 `Deref` 和 `Drop` 特征,这两个特征可以智能地帮助我们节省使用上的负担:
|
|
|
|
impl Person {
|
|
|
|
|
|
|
|
fn new(name: String, age: u8) -> Self {
|
|
|
|
|
|
|
|
Person { name, age}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn display(self: &mut Person, age: u8) {
|
|
|
|
|
|
|
|
let Person{name, age} = &self;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
以上代码有一个很奇怪的地方:在 `display` 方法中,`self` 是 `&mut Person` 的类型,接着我们对其取了一次引用 `&self`,此时 `&self` 的类型是 `&&mut Person`,然后我们又将其和 `Person` 类型进行匹配,取出其中的值。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
那么问题来了,Rust 不是号称安全的语言吗?为何允许将 `&&mut Person` 跟 `Person` 进行匹配呢?答案就在本章节中,等大家学完后,再回头自己来解决这个问题 :) 下面正式开始咱们的新章节学习。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
何为智能指针?能不让你写出 `****s` 形式的解引用,我认为就是智能: ),智能指针的名称来源,主要就在于它实现了 `Deref` 和 `Drop` 特征,这两个特征可以智能地帮助我们节省使用上的负担:
|
|
|
|
|
|
|
|
|
|
|
|
- `Deref` 可以让智能指针像引用那样工作,这样你就可以写出同时支持智能指针和引用的代码,例如 `*T`
|
|
|
|
- `Deref` 可以让智能指针像引用那样工作,这样你就可以写出同时支持智能指针和引用的代码,例如 `*T`
|
|
|
|
- `Drop` 允许你指定智能指针超出作用域后自动执行的代码,例如做一些数据清除等收尾工作
|
|
|
|
- `Drop` 允许你指定智能指针超出作用域后自动执行的代码,例如做一些数据清除等收尾工作
|
|
|
|
|
|
|
|
|
|
|
|
下面先来看看 `Deref` 特征是如何工作的。
|
|
|
|
先来看看 `Deref` 特征是如何工作的。
|
|
|
|
|
|
|
|
|
|
|
|
## 通过 `*` 获取引用背后的值
|
|
|
|
## 通过 `*` 获取引用背后的值
|
|
|
|
|
|
|
|
|
|
|
|
在正式讲解 `Deref` 之前,我们先来看下常规引用的解引用。
|
|
|
|
在正式讲解 `Deref` 之前,我们先来看下常规引用的解引用。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
常规引用是一个指针类型,包含了目标数据存储的内存地址。对常规引用使用 `*` 操作符,就可以通过解引用的方式获取到内存地址对应的数据值:
|
|
|
|
常规引用是一个指针类型,包含了目标数据存储的内存地址。对常规引用使用 `*` 操作符,就可以通过解引用的方式获取到内存地址对应的数据值:
|
|
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|