Rust所有权和内存分析图解

本文概述

  • 了解所有权
  • 什么是所有权?
  • 所有权要点
  • 所有权规则
  • 所有权示例
  • 内存和分配
  • 步骤1
  • 第2步
  • 第三步
  • 复制特征的使用
  • 所有权和职能
  • 返回值和范围
了解所有权 所有权是Rust编程语言提供的独特功能, 并且无需使用垃圾收集器或指针就可以保证内存安全。
什么是所有权? 当代码块拥有资源时, 称为资源所有权。代码块创建一个包含资源的对象。当控件到达块的末尾时, 对象被销毁, 资源被释放。
所有权要点
  • “ 所有者” 可以根据可变性来更改变量的所有者值。
  • 所有权可以转移到另一个变量。
  • 所有权只是Rust中移动的语义。
  • 所有权模型还保证了安全性。
所有权规则
  • 在Rust中, 每个值都有一个与之关联的变量, 称为其所有者。
  • 一次只能有一个所有者。
  • 当所有者超出范围时, 与之关联的值将被销毁。
所有权示例 多个变量可以在Rust中相互交互。让我们看一个例子:
将x的值分配给变量y:
let x=10; let y=x;

在上面的示例中, x绑定到值10。然后, x的值分配给变量y。在这种情况下, 不会创建x的副本, 而是将x的值移动到变量y。因此, x的所有权转移到变量y, 并且变量x被破坏。如果我们尝试重用变量x, 则Rust会引发错误。让我们通过一个例子来理解这一点。
fn main(){ let x=10; let y=x; println!("value of x :{}", x); }

以下是以上示例的输出:
Rust所有权和内存分析图解

文章图片
内存和分配 在Rust中, 数据可以存储在堆栈或堆内存中。
Rust所有权和内存分析图解

文章图片
堆栈内存:在堆栈内存中, 数据始终按顺序放置, 然后以相反的顺序删除。它遵循” 后进先出” 的原则, 即, 总是首先删除最后插入的数据。堆栈内存是有组织的内存。由于它访问内存的方式, 它比堆内存快。如果在编译时数据大小未知, 则使用堆内存来存储内容。
堆内存:堆内存是有组织的内存。操作系统在堆内存中找到一个空白空间并返回一个指针。此过程称为” 在堆上分配” 。
Rust所有权和内存分析图解

文章图片
此图显示堆栈包含指针, 而堆包含内容。
让我们看一个简单的内存分配示例。
fn main(){let v1=vec![1, 2, 3]; let v2=v1; }

步骤1 在程序的第一条语句中, 向量v1与值1, 2和3绑定。向量由三部分组成, 即指向存储器的指针, 该指针指向存储在存储器中的数据, 长度和容量。向量。这些部分存储在堆栈中, 而数据存储在堆内存中, 如下所示:
Rust所有权和内存分析图解

文章图片
第2步 在第二个程序语句中, 将向量v1分配给向量v2。指针, 长度和容量被复制到堆栈上, 但是我们不将数据复制到堆内存中。让我们看一下内存表示形式:
Rust所有权和内存分析图解

文章图片
但是, 这种表示形式会产生问题。当v1和v2都超出范围时, 则两者都将尝试释放内存。这将导致双倍的可用内存, 并导致内存损坏。
第三步 Rust避免了第2步的情况, 以确保内存安全。 Rust不复制分配的内存, 而是认为v1向量不再有效。因此, 当v1超出范围时, 不需要释放v1的内存。
Rust所有权和内存分析图解

文章图片
复制特征的使用 复制特征是一个特殊的注释, 它被放置在存储在堆栈上的整数之类的类型上。如果在类型上使用了复制特征, 那么即使在赋值操作之后, 也可以进一步使用较旧的变量。
以下是一些复制类型:
  • 所有整数类型, 例如u32。
  • 布尔类型, 布尔值true或false。
  • 所有浮动类型, 例如f64。
  • 字符类型, 字符。
所有权和职能 将变量传递给函数时, 所有权将移至被调用函数的变量。传递值的语义等于将值分配给变量。
让我们通过一个例子来理解这一点:
fn main(){let s=String::from("srcmini"); take_ownership(s); let ch='a'; moves_copy(ch); println!("{}", ch); }fn take_ownership(str:String){ println!("{}", str); }fn moves_copy(c:char){println!("{}", c); }

【Rust所有权和内存分析图解】输出
srcminiaa

在上面的示例中, 字符串” s” 与值” srcmini” 绑定, 并且” s” 变量的所有权通过take_ownership()函数传递给变量” str” 。 ” ch” 变量与值” a” 绑定, 并且” ch” 变量的所有权通过move_copy()函数传递给变量” c” 。此后也可以使用” ch” 变量, 因为此变量的类型是” 复制” 特征。
返回值和范围 从函数返回值也将转移所有权。让我们来看一下:
fn main(){let x= gives_ownership(); println!("value of x is {}", x); }fn gives_ownership()-> u32{let y=100; y}

输出
value of x is 100

在上述示例中, gives_ownership()函数返回y的值, 即100, 并将y变量的所有权转移到x变量。

    推荐阅读