📅  最后修改于: 2020-11-02 04:17:01             🧑  作者: Mango
程序的内存可以在以下位置分配-
堆栈遵循后进先出的顺序。堆栈存储在编译时已知大小的数据值。例如,固定大小为i32的变量是堆栈分配的候选对象。它的大小在编译时已知。由于大小固定,所有标量类型都可以存储在堆栈中。
考虑一个字符串示例,该字符串在运行时分配一个值。这样的字符串的确切大小不能在编译时确定。因此,它不是堆栈分配的候选人,而是堆分配的候选人。
堆存储器存储在编译时大小未知的数据值。它用于存储动态数据。简而言之,将堆内存分配给在程序的整个生命周期中可能发生变化的数据值。堆是内存中与堆栈相比组织较少的区域。
Rust中的每个值都有一个变量,称为该值的所有者。 Rust中存储的每个数据都会有一个与之关联的所有者。例如,在语法中-let age = 30,age是值30的所有者。
每个数据一次只能拥有一个所有者。
两个变量不能指向相同的存储位置。变量将始终指向不同的存储位置。
价值的所有权可以通过-转移
将一个变量的值分配给另一个变量。
将值传递给函数。
从函数返回值。
Rust作为一种语言的主要卖点是其内存安全性。通过严格控制谁可以在什么时候使用限制来实现内存安全。
考虑以下代码片段-
fn main(){
let v = vec![1,2,3];
// vector v owns the object in heap
//only a single variable owns the heap memory at any given time
let v2 = v;
// here two variables owns heap value,
//two pointers to the same content is not allowed in rust
//Rust is very smart in terms of memory access ,so it detects a race condition
//as two variables point to same heap
println!("{:?}",v);
}
上面的示例声明了一个向量v。所有权的思想是,只有一个变量绑定到资源, v绑定到资源或v2绑定到资源。上面的例子抛出一个错误-使用移动值`v` 。这是因为资源的所有权已转移到v2。这意味着所有权从v移到v2(v2 = v),并且在移动后v无效。
当我们将堆中的对象传递给闭包或函数时,值的所有权也会发生变化。
fn main(){
let v = vec![1,2,3]; // vector v owns the object in heap
let v2 = v; // moves ownership to v2
display(v2); // v2 is moved to display and v2 is invalidated
println!("In main {:?}",v2); //v2 is No longer usable here
}
fn display(v:Vec){
println!("inside display {:?}",v);
}
当函数执行完成时,传递给函数的所有权将失效。一种解决方法是让函数将拥有的对象返回给调用者。
fn main(){
let v = vec![1,2,3]; // vector v owns the object in heap
let v2 = v; // moves ownership to v2
let v2_return = display(v2);
println!("In main {:?}",v2_return);
}
fn display(v:Vec)->Vec {
// returning same vector
println!("inside display {:?}",v);
}
如果是基本类型,则将一个变量的内容复制到另一个变量。因此,没有所有权变动发生。这是因为原始变量比对象需要更少的资源。考虑以下示例-
fn main(){
let u1 = 10;
let u2 = u1; // u1 value copied(not moved) to u2
println!("u1 = {}",u1);
}
输出为– 10。