Rust实用特性:Clone、Copy、Deref等特性深入解析
立即解锁
发布时间: 2025-09-05 01:00:56 阅读量: 14 订阅数: 42 AIGC 


Rust编程:从入门到精通
# Rust 实用特性:Clone、Copy、Deref 等特性深入解析
## 1. Clone 特性
在 Rust 中,`Clone` 特性用于创建对象的副本。当执行 `s = t.clone();` 时,通常会克隆 `t`,丢弃 `s` 的旧值,然后将克隆的值移动到 `s` 中,这涉及一次堆分配和一次堆释放。但如果 `s` 原有的堆缓冲区有足够的容量来容纳 `t` 的内容,就无需进行分配和释放操作,只需将 `t` 的文本复制到 `s` 的缓冲区并调整长度即可。
在泛型代码中,应尽可能使用 `clone_from` 以利用可能存在的优化实现。如果你的 `Clone` 实现只是对类型的每个字段或元素应用 `clone`,然后从这些克隆值构造一个新值,并且 `clone_from` 的默认定义足够好,那么可以使用 `#[derive(Clone)]` 让 Rust 自动为你实现:
```rust
#[derive(Clone)]
struct MyType;
```
标准库中大多数有意义复制的类型都实现了 `Clone` 特性,如基本类型 `bool` 和 `i32`,容器类型 `String`、`Vec<T>` 和 `HashMap` 等。但有些类型不适合复制,如 `std::sync::Mutex`,它们没有实现 `Clone` 特性。还有些类型如 `std::fs::File` 可以复制,但复制可能会因操作系统资源不足而失败,因此它们不实现 `Clone`(因为 `clone` 必须是无错误的),而是提供 `try_clone` 方法,该方法返回 `std::io::Result<File>` 以报告失败情况。
## 2. Copy 特性
对于大多数类型,赋值操作会移动值而不是复制。但简单的不拥有任何资源的类型可以是 `Copy` 类型,赋值时会复制源值,而不是移动并使源值未初始化。
一个类型如果实现了 `std::marker::Copy` 标记特性,那么它就是 `Copy` 类型,该特性定义如下:
```rust
trait Copy: Clone { }
```
为自定义类型实现 `Copy` 很简单:
```rust
impl Copy for MyType { }
```
但由于 `Copy` 是一个对语言有特殊意义的标记特性,Rust 只允许类型在只需要浅字节逐字节复制时实现 `Copy`。拥有堆缓冲区或操作系统句柄等其他资源的类型不能实现 `Copy`。任何实现了 `Drop` 特性的类型也不能是 `Copy` 类型,因为 Rust 假定需要特殊清理代码的类型也需要特殊的复制代码。
和 `Clone` 一样,可以使用 `#[derive(Copy)]` 让 Rust 自动为你实现,通常会同时使用 `#[derive(Copy, Clone)]`。不过在将类型设为 `Copy` 之前要仔细考虑,虽然这样会使类型更易用,但会对其实现施加严格限制,隐式复制也可能代价高昂。
## 3. Deref 和 DerefMut 特性
通过实现 `std::ops::Deref` 和 `std::ops::DerefMut` 特性,可以指定解引用运算符(如 `*` 和 `.`)在自定义类型上的行为。指针类型如 `Box<T>` 和 `Rc<T>` 实现了这些特性,以便它们能像 Rust 的内置指针类型一样工作。
这两个特性的定义如下:
```rust
trait Deref {
type Target: ?Sized;
fn deref(&self) -> &Self::Target;
}
trait DerefMut: Deref {
fn deref_mut(&mut self) -> &mut Self::Target;
}
```
`deref` 和 `deref_mut` 方法接受 `&Self` 引用并返回 `&Self::Target` 引用。`Target` 应该是 `Self` 包含、拥有或引用的内容,例如对于 `Box<Complex>`,`Target` 类型是 `Complex`。`DerefMut` 扩展了 `Deref`,如果能解引用并修改某个值,那么也应该能借用其共享引用。
`Deref` 和 `DerefMut` 特性还用于自动类型转换。当插入 `deref` 调用可以避免类型不匹配时,Rust 会自动插入。实现 `DerefMut` 则允许对可变引用进行相应的转换,这称为解引用强制转换。
例如,对于以下 `Selector` 类型:
```rust
struct Selector<T> {
elements: Vec<T>,
current: usize
}
```
要使其表现得像文档注释中描述的那样,需要为其实现 `Deref` 和 `DerefMut` 特性:
```rust
use std::ops::{Deref, DerefMut};
impl<T> Deref for Selector<T> {
type Target = T;
fn deref(&self) -> &T {
&self.elements[self.current]
}
}
impl<T> DerefMut for Selector<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.elements[self.current]
}
}
```
使用示例如下:
```rust
let mut s = Selector { elements: vec!['x', 'y', 'z'],
current: 2 };
assert_eq!(*s, 'z');
assert!(s.is_alphabetic()
```
0
0
复制全文
相关推荐









