Introduction 介绍
Ownership is a unique memory management system where each value has a designated owner, ensuring automatic memory deallocation when the owner goes out of scope, eliminating common memory-related bugs. This ownership model enhances safety and performance in systems programming.
所有权是一个独特的内存管理系统,其中每个值都有一个指定的所有者,确保在所有者超出范围时自动释放内存,消除常见的内存相关错误。这种所有权模型增强了系统编程的安全性和性能。
The stack and The heap
栈和堆
Most programming languages don't require you to bother about where and how the data is stored but in a low level programming language. It makes all of the difference.
大多数编程语言不需要你去关心数据存储在哪里以及如何存储,而是用低级编程语言。这让一切都不同了。
The stack is a region of memory used for function call management and local variables.
堆栈是用于函数调用管理和局部变量的内存区域。
The heap is a dynamic memory area for allocating and deallocating memory during runtime in a program.
堆是一个动态内存区域,用于在程序运行时分配和释放内存。
How it works? 它是如何工作的?
During runtime our program has access to both the stack and the heap. The stack is a fixed size memory that stores stack frames for each function call and variable. The heap is dynamic in size and can store any amounts of data.
在运行时,我们的程序可以访问堆栈和堆。堆栈是一个固定大小的内存,用于存储每个函数调用和变量的堆栈帧。堆的大小是动态的,可以存储任何数量的数据。
Example: 范例:
ba
fn main(){
fn a(){
let z: String = Strng::from("Hello Wrold");
b();
}
fn b(){
let x: u8 = 5;
let y: &str = "hello";
}
a();
}
Function A is called first so we create a stack frame. String
type can be dynamic in size so we allocate some memory in the heap and store the value there
首先调用函数A,因此我们创建一个堆栈帧。 String
类型的大小可以是动态的,所以我们在堆中分配一些内存并将值存储在那里
Then function b is called, here x
is an unsigned 8 bit integer, so we can directly store it in the stack memory. now y
is a string literal, which will be stored in the executable.
然后调用函数B,这里 x
是一个无符号的8位整数,所以我们可以直接将其存储在堆栈内存中。现在 y
是一个字符串文字,它将存储在可执行文件中。
Ownership 所有权
The rules of ownership 所有权规则
- Each value in Rust has a unique owner.
Rust中的每个值都有唯一的所有者。 - There can only be one owner at a time, preventing multiple parts of the program from modifying the data concurrently.
一次只能有一个所有者,防止程序的多个部分同时修改数据。 - Ownership can be transferred through ownership transfer and borrowed through references.
所有权可以通过所有权转移进行转移,也可以通过参照物进行借用。 - When the owner goes out of scope the value is dropped
当所有者超出范围时,值将被删除
Example: 范例:
ba
fn main(){
{ //var is not valid here, it is not declared yet...
let var: &str = "Hello"; // var is valid from here
} // The scope is over, var is no longer valid
}
Memory and allocation 内存和分配
Multiple variables can interact with the same data in different ways in Rust.
在Rust中,多个变量可以以不同的方式与相同的数据交互。
Example: 范例:
ba
fn main(){
let x: u8 = 5;
let y = x;
println!("X = {}, Y = {}",x,y);
}
This copies the value of x
to y
, so the output is
这将 x
的值复制到 y
,因此输出为
ba
X = 5, Y = 5
But then: 但随后:
ba
fn main(){
let str1: String = String::from("Hello, World!");
let str2: String = str1;
}
We would assume that the same would happen here, but to ensure memory safety. str1
is invalidated and the String Hello, World!
is moved into str2
.
我们假设这里也会发生同样的事情,但要确保内存安全。 str1
无效,字符串 Hello, World!
被移到 str2
中。
The Stack and heap diagram would look something like this
堆栈和堆图看起来像这样
Although we have the functionality to clone the strings :
虽然我们有克隆字符串的功能:
ba
fn main(){
let str1: String = String::from("Hello, World!");
let str2: String = str1.clone();
}
Ownership and Functions 所有权和职能
Passing a variiable in a function as an argument has the same effect as assigning it to a different variable. The function takes the ownership of the variable.
在函数中传递一个变量作为参数与将它赋给另一个变量具有相同的效果。该函数获取变量的所有权。
ba
fn main(){
let str1: String = String::from("Hello");
takes_ownership(str1);
println!("{}", str1); // this would result in an error
}
fn takes_ownership(some_string: String){
println!("{}",some_string);
}
This code will result in an error because, we have given the ownership of str1
to the takes_ownership
function. So effectively str1
is dropped when we try to print it on line 4
这段代码将导致一个错误,因为我们已经将 str1
的所有权交给了 takes_ownership
函数。因此,当我们尝试在 line 4
上打印时, str1
实际上被丢弃
This also works in the opposite way. Just like a function can take ownership of a variable. It can also give ownership of a variable\
这也以相反的方式工作。就像一个函数可以拥有一个变量。它还可以给予变量的所有权。
Example: 范例:
ba
fn main(){
let str1: String = gives_ownership();
println!("String 1 : {}",str1);
}
fn gives_ownership() -> String {
let some_string: String = String::from("Hello World");
some_string
}
This piece of code takes the variable some_string
and returns the variable, we store the return value in the str1
variable effectively making str1
the owner of the value Hello World
.
这段代码接受变量 some_string
并返回该变量,我们将返回值存储在 str1
变量中,有效地使 str1
成为值 Hello World
的所有者。