Rust中的变量有一个叫做所有权的概念。此概念的官网介绍如下:
- Rust 中的每一个值都有一个被称为其 所有者(owner)的变量。
- 值有且只有一个所有者。
- 当所有者(变量)离开作用域,这个值将被丢弃。
*以上来自网站: https://kaisery.github.io/trpl-zh-cn/ch04-01-what-is-ownership.html
在Rust中,String,Vec<T>等数据类型是放在heap上面的,他们都实现了drop trait,有点类似于C++的destructor,当变量离开作用域的时候,会自动call 变量实现的drop trait,将变量从heap中清除。因此,Rust得以在不使用GC的情况之下实现堆内存回收。
与此同时,在堆上面的变量一般都满足move semantic,根据我的理解,此性质跟C++也非常类似。当我们把一个存放在堆上面的变量赋值给同样类型的变量的时候,Rust实际上是把值的ownership给move给了新的变量,而不是把值再copy一遍。当变量的所有权move之后,原变量就不再享有值的所有权。比如:
let s = String::from("good");
let b = s;
println!("{}",s);
上述代码会产生compiling error,信息如下:
let b = s;
| - value moved here
| println!("{}",s);
| ^ value borrowed here after move
意思是,当我们把s赋值给b的时候,实际上是b获取了值的所有权,而非重新copy一份新的值。
但是,Rust中的基本数据类型,比如i32,char,u8,是实现了Copy trait的,也就是拷贝语义,即旧值赋值之后,仍然存在,并且可以正常使用。同时,只含有基本数据类型的array和tuple也是实现了拷贝语义的。根据Rust的官方说明,这些数据实际上是放在栈上面,而不是堆上面。我们来看例子:
let a1:[i32;4]=[0;4];
let mut a2 = a1;
a2[1] = 3333;
println!("a1 is: {:?}, a2 is: {:?}",a1,a2);
运行结果如下:
a1 is: [0, 0, 0, 0], a2 is: [0, 3333, 0, 0]
我们可以看到,改变a2的值,并没有改变a1的值。这是两份完全不同的数据。与此同时,a1对[0,0,0,0]享有所有权,a2对[0,3333,0,0]享有所有权。每个值有且只有一个拥有者。只不过,array的数据放在栈上面,String的数据放在堆上面。
本文探讨了Rust编程语言中的所有权概念,解释了每个值只有一个所有者,当所有者离开作用域时值会被丢弃。Rust通过所有权实现堆内存回收,避免使用垃圾收集器。详细介绍了堆上变量(如Box)的转移所有权特性,以及基本数据类型(如i32)的拷贝语义。举例展示了如何在不同变量间转移所有权以及拷贝语义的区别。
547





