rust语义:move、copy

rust没有gc,但是保证了内存管理,是怎样做到的呢,主要是靠move、copy的语义做到的。

move

rust规定了move语义

  • Each value in Rust has a variable that’s called its owner)
  • There can only be one owner at a time
  • When the owner goes out of scope, the value will be dropped

例如:

fn main() {
    let data = vec![1, 2, 3, 4];
    let data1 = data;
    println!("sum of data1: {}", sum(data1));
    println!("data1: {:?}", data1); // error1
    println!("sum of data: {}", sum(data)); // error2
}

fn sum(data: Vec) -> u32 {
    data.iter().fold(0, |acc, x| acc + x)
}

这段代码编译报错


4 |     let data1 = data;
  |         ----- move occurs because `data1` has type `Vec`, which does not implement the `Copy` trait
5 |     println!("sum of data1: {}", sum(data1));
  |                                      ----- value moved here
6 |     println!("data1: {:?}", data1); // error1
  |                             ^^^^^ value borrowed here after move

error[E0382]: use of moved value: `data`
 --> src/main.rs:7:37
  |
3 |     let data = vec![1, 2, 3, 4];
  |         ---- move occurs because `data` has type `Vec`, which does not implement the `Copy` trait
4 |     let data1 = data;
  |                 ---- value moved here
...
7 |     println!("sum of data: {}", sum(data)); // error2
  |                                     ^^^^ value used here after move

这里报错,因为在sum(data1)的时候,所有权已经转移到函数参数中,再访问data1就会报错。这就是move语义

Copy语义

当有的时候,我们需要稍后继续使用值,那么move语义就不够用了,这里就产生了copy语义。
参见 https://doc.rust-lang.org/std/marker/trait.Copy.html
rust内置实现了很多类型的copy语义,总结一下:

  • 原生类型,包括函数、不可变引用和裸指针实现了 Copy;
  • 数组和元组,如果其内部的数据结构实现了 Copy,那么它们也实现了 Copy;
  • 可变引用没有实现 Copy;
  • 非固定大小的数据结构,没有实现 Copy。

例如


fn main() {
    let a = 3;
    let b = 4;
    let c = sum(a, b);
    println!("{}", a);
}

fn sum(a: i32, b: i32) -> i32 {
    return a + b;
}

这里是不报错的,因为i32实现了copy语义,在调用sum的时候,参数会进行copy。

小结

rust通过规则的限制实现了内存的管理,限制产生了明确从而也诞生了创新。

你可能感兴趣的:(rust语义:move、copy)