橘子味的心
标题:Rust所有权

所有权是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中,数据可以存储在堆栈或堆内存中。

堆栈存储器: 在堆栈存储器中,数据始终按顺序放置并以相反的顺序移除。 它遵循“后进先出”的原则,即始终首先删除最后插入的数据。 堆栈内存是一种有组织的内存。 它比堆内存更快,因为它访问内存的方式。 如果在编译时数据的大小未知,则堆内存用于存储内容。

堆内存: 堆内存是有组织的内存。 操作系统在堆内存中找到一个空的空格并返回一个指针。 此过程称为“在堆上分配”。

此图显示堆栈包含指针,而堆包含内容。

下面来看一个简单的内存分配示例。

 fn main()  
{  
  let v1=vec![1,2,3];  
  let v2=v1;  
}

第1步:
在程序的第一个语句中,向量v1与值1,23绑定。向量由三部分组成,即指向存储器中指向存储在内存中的数据的指针,长度和向量的容量。 这些部分存储在堆栈中,而数据存储在堆内存中,如下所示:

第2步:
在程序的第二个语句中,将v1向量分配给向量v2。 指针,长度和容量将复制到堆栈中,但不会将数据复制到堆内存中。现在内存的表示如下:

但是,这种表示形式可能会产生问题。 当v1v2都超出范围时,两者都会尝试释放内存。 这会导致双重空闲内存,这会导致内存损坏。

第3步:
Rust避免了第2步 条件以确保内存安全。 Rust没有复制分配的内存,而是认为v1向量不再有效。 因此,当v1超出范围时,它不需要释放v1的内存。

使用复制特征

复制特征是一种特殊的注释,它放在存储在堆栈上的整数类型上。 如果在类型上使用了复制特征,则即使在赋值操作之后也可以进一步使用旧变量。

以下是一些复制类型:

  • 所有整数类型,如u32
  • 布尔类型-bool,其值为truefalse
  • 所有浮动类型,如f64
  • 字符类型,如char

所有权和函数

当变量传递给函数时,所有权将移动到被调用函数的变量。 传递值的语义等于为变量赋值。

下面通过一个例子来理解这一点:

fn main()  
{  
  let s=String::from("Yiibai");  
  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);  
}

执行上面示例代码,得到以下结果 -

Yiibai
a
a

在上面的例子中,字符串s与值Yiibai绑定,s变量的所有权通过take_ownership()函数传递给变量strch变量与值a绑定,ch变量的所有权通过moves_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

在上面的例子中,give_ownership()函数返回y的值,即100y变量的所有权被转移到x变量。


分类