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

相关推荐
汤姆和佩琦16 分钟前
2024-12-25-sklearn学习(20)无监督学习-双聚类 料峭春风吹酒醒,微冷,山头斜照却相迎。
学习·聚类·sklearn
IT女孩儿19 分钟前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_7482389220 分钟前
webgis入门实战案例——智慧校园
开发语言·ios·swift
好学近乎知o28 分钟前
正则表达式(学习Django过程中可能涉及的)
学习·正则表达式·django
雨中奔跑的小孩31 分钟前
爬虫学习案例8
爬虫·学习
jieshenai32 分钟前
使用 VSCode 学习与实践 LaTeX:从插件安装到排版技巧
ide·vscode·学习
Clockwiseee34 分钟前
PHP伪协议总结
android·开发语言·php
小灰灰搞电子35 分钟前
Qt实现Android的图案密码(图形解锁)源码分享
开发语言·qt
m0_675988231 小时前
Leetcode3218. 切蛋糕的最小总开销 I
c++·算法·leetcode·职场和发展
吴冰_hogan2 小时前
JVM(Java虚拟机)的组成部分详解
java·开发语言·jvm