学习Rust的第6天:所有权模型简介

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 的所有者。

相关推荐
算家云1 分钟前
快速识别模型:simple_ocr,部署教程
开发语言·人工智能·python·ocr·数字识别·检测模型·英文符号识别
Thomas_Cai12 分钟前
Python后端flask框架接收zip压缩包方法
开发语言·python·flask
霍先生的虚拟宇宙网络14 分钟前
webp 网页如何录屏?
开发语言·前端·javascript
温吞-ing16 分钟前
第十章JavaScript的应用
开发语言·javascript·ecmascript
Bald Baby17 分钟前
JWT的使用
java·笔记·学习·servlet
魔道不误砍柴功23 分钟前
实际开发中的协变与逆变案例:数据处理流水线
java·开发语言
鲤籽鲲31 分钟前
C# MethodTimer.Fody 使用详解
开发语言·c#·mfc
亚图跨际34 分钟前
Python和R荧光分光光度法
开发语言·python·r语言·荧光分光光度法
Rverdoser42 分钟前
RabbitMQ的基本概念和入门
开发语言·后端·ruby
dj24429457071 小时前
JAVA中的Lamda表达式
java·开发语言