Clone
Rust 语法上一个变量的值是转移给另一个变量, 但是有些情况下可能会想变量值转移之后, 自身还能继续使用. 可以使用 clone 函数
1
2
3
4
5 1let a = String::from("test");
2let b = a.clone();
3println!("{}", a);
4复制代码
5
clone 这个函数是在标准库的 std::clone::Clone trait 里, 既然是个 trait, 也就意味着可以自己实现一套操作, 通常情况下用默认的定义就好了.
Copy
我们现在了解到每次绑定变量, 都会发生所有权转移, 但是你会发现写有些东西的时候好像行为跟目前的认知有点不一样.
1
2
3
4
5 1let a: i32 = 10;
2let b = a;
3println!("a = {}", a); // a = 10
4复制代码
5
a 没有使用 clone 还能使用, 原因是 Rust 有部分类型默认实现了 std::marker::Copy trait. 像 structs 这类没有默认实现的类型, 想要这样就得实现一下 Copy.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 1fn main() {
2 let p1 = Point { x: 1.0, y: 1.0 };
3 let p2 = p1;
4 println!("p1 = {:?}", p1);
5}
6
7#[derive(Debug)]
8struct Point {
9 x: f64,
10 y: f64,
11}
12
13impl Copy for Point {}
14复制代码
15
但是其实这样还是没法用的, 编译后就报错了, 因为 struct Point 没有实现 Clone trait.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 1pub fn main_8_6() {
2 let p1 = Point { x: 1.0, y: 1.0 };
3 let p2: Point = p1;
4 println!("p1 = {:?}", p1);
5}
6
7#[derive(Debug)]
8struct Point {
9 x: f64,
10 y: f64,
11}
12
13impl Clone for Point {
14 fn clone(&self) -> Self {
15 Self { x: self.x, y: self.y }
16 }
17}
18
19impl Copy for Point {}
20复制代码
21
现在终于好使了. 但是我们发觉做这些操作非常烦, 我们注意到 #[derive(Debug)] 这个东西, 刚好 Rust 提供了Clone, Copy 的属性.
1
2
3
4
5
6
7
8
9
10
11
12
13 1pub fn main_8_6() {
2 let p1 = Point { x: 1.0, y: 1.0 };
3 let p2: Point = p1;
4 println!("p1 = {:?}", p1);
5}
6
7#[derive(Debug, Clone, Copy)]
8struct Point {
9 x: f64,
10 y: f64,
11}
12复制代码
13
Rust 默认绑定变量是进行 move 行为, 想要保留 move 前的变量, 可以使用 clone 函数, 想要实现基本类型一样的 copy 行为, 我们可以添加 Clone, Copy 属性.