一、常用trait
Clone&Copy
rust
pub trait Clone: Sized {
fn clone(&self) -> Self;
}
pub trait Copy: Clone { }
|-------|------|------------|--------------------|
| Clone | Copy | let y = x; | let y = x.clone(); |
| | | 发生移动 | 编译报错 |
| √ | | 发生移动 | 发生拷贝 |
| √ | √ | 发生拷贝 | 发生拷贝 |
Clone:可以理解为深拷贝,例如String的clone就是将栈上的指针和堆上的字符都拷贝一份。
若某类型实现了Clone,则y=x仅仅只是移动所有权,若想做深拷贝必须显式调用.clone()
Copy:逐比特拷贝。 因此Copy不能被重载。
若某类型实现了Copy,则y=x就进行的是拷贝而非移动。
若结构体的每个字段都实现了Copy,rust编译器不会自动为该结构体生成Copy trait,即y=x仍然会发生移动。只有加上#[derive(Copy, Clone)]才行。
不可变引用&T也是实现了Copy的。就算T不可Copy,&T也是可Copy的。
可变引用&mut T不可Copy。
实现了Copy就不能实现Drop,实现了Drop就不能实现Copy。
二、遍历
按值遍历(该种方式会将v移动掉,后续无法再使用)
rust
let v = vec![1, 2, 3, 4, 5];
for x in v { // 等价于v.into_iter()。 x是i32类型
println!("{x}");
}
按不可变引用遍历:
rust
let v = vec![1, 2, 3, 4, 5];
for x in &v { // 等价于v.iter()。 x是&i32类型
println!("{x}");
}
按可变引用遍历:
rust
let mut v = vec![1, 2, 3, 4, 5];
for x in &mut v { // 等价于v.iter_mut()。 x是&mut i32类型
println!("{x}");
}