📜  Rust所有权

📅  最后修改于: 2021-01-08 13:36:22             🧑  作者: Mango

锈迹所有权

了解所有权

所有权是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,2和3绑定。向量由三部分组成,即指向内存的指针,该指针指向存储在内存中的数据,指针的长度和容量。向量。这些部分存储在堆栈中,而数据存储在堆内存中,如下所示:

第2步:

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

但是,这种表示形式会产生问题。当v1和v2都超出范围时,则两者都将尝试释放内存。这将导致双倍的可用内存,并导致内存损坏。

第三步:

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

复制特征的使用

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

以下是一些复制类型:

  • 所有整数类型,例如u32。
  • 布尔类型,布尔值true或false。
  • 所有浮动类型,例如f64。
  • 字符类型,字符。

所有权和职能

将变量传递给函数,所有权将移至被调用函数的变量。传递值的语义等于将值分配给变量。

让我们通过一个例子来理解这一点:

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

输出:

javaTpoint
a
a

在上面的示例中,字符串“ s”与值“ javaTpoint”绑定,并且“ s”变量的所有权通过take_ownership()函数传递给变量“ str”。 'ch'变量与值'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

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