Rust你不认识的所有权

在Rust中是没有内存垃圾回收机制(GC)的,那Rust是如何保障内存安全的呢?这就引出了“所有权”这个概念。

我们看下下面这段伪代码

let s = "helloString";
t = s;
print(s);

在之前我们学习的语言中,比如C语言,对于上述伪代码的执行结果应该是正常打印"helloString" 的内容,但是在Rust中,执行上述代码时,会出现如下提示

------ 增加所有权返回内容;

而产生这个结果的原因就是触发了Rust语言中所有权机制:

  • Rust中的每一个值都有一个对应的变量作为它的所有者
  • 在同一时间内,值有且仅有一个所有者
  • 当所有者离开自己的作用域时,它持有的值就会被释放掉

在看这三条机制之前,需要先说明一下Rust中变量作用域的概念

作用域:一个对象在程序中有效的范围。

比如如下Rust代码

{
    let s = "hello";
}

在花括号内部就是变量s的作用域,当源码超出这个范围后,变量s将不再可用,即

{
    let s = "hello";
}
println!("{}", s);

打印这一句代码编译时会报错。因为在Rust语言中,当变量离开作用域时Rust会自动调用变量的"drop"函数,以此保障内存的快速回收。上述源码中,在代码执行到“}”时,Rust调用了变量s的drop函数,所以s指向的内存失效,从而导致在执行打印语句时会出错,也就是这个逻辑保障了Rust语言中内存的安全性。

我们再说回文章开头的伪代码例子,为什么编译时会出现问题,这里我们就要详细介绍一下这些语句在Rust中的逻辑。

let s = "helloString";

这句语句是声明了一个变量并使用“helloString”进行了初始化

简化展示,隐藏内部详细逻辑

t = s;

这个语句是将变量s的内容同时赋值给变量t,如下图,如果每次赋值的时候都全量内存拷贝一份的话,那整体语言性能会下降很多(毕竟变量地址大小还是不可确定的),所以处理方式是新建一个变量t,然后将内容内存指向s的指向地址。

上述情况下就出现了一个情况,同一个值被两个变量所指向,这个不符合Rust所有权的规则,所以Rust根据所有权做了一个语言限制,即当s赋值给新的变量t时,变量t指向s指向的内容,而变量s本身将被Rust擦除,所以在执行完赋值语句后,等号右侧(也就是s)将无效,在Rust语言中将这个行为叫做变量的移动,从字面意思理解也就是将变量s所有的值移动到变量t中,移动完成后s的生命周期也随之结束。

Rust有了移动这个概念,那对于其他语言中的深度拷贝或再次赋值的情况下Rust中该如何做呢?为了解决这个问题,Rust提出了另外一个变量与数据的交互方式——克隆,意思就是将s的数据完整的克隆一份给t,s的内容不变:

以Rust字符串数据结构为例子,可参考如下:

let s1 = String::from("hello");
let s2 = s1.clone();  // 此处为克隆的默认方法
println!("s1={}, s2={}", s1, s2); 

从执行结果可以看出,克隆后s1变量内容不变,还可以继续使用。

上述就是Rust所有权的一些学习心得。

到此这篇关于Rust你不认识的所有权的文章就介绍到这了,更多相关Rust所有权内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Rust 编程语言中的所有权ownership详解

    目录 I. 前言 II. Rust Ownership概述 III. Ownership的代码实践 IV. Ownership与内存管理 首先和c++相比 和我们熟悉的jvm垃圾回收相比 V. 总结 I. 前言 Rust,不少程序员的白月光,这里我们简单罗列一些大牛的评价. Linus Torvalds:Linux内核的创始人,对Rust的评价是:“Rust的主要优点是代码的安全性和速度,很难在C++中实现这种安全性,而且Rust编译器会捕获很多C++难以发现的错误”. Brian Kernig

  • Rust 所有权机制原理深入剖析

    目录 what's ownership? Scope (作用域) ownership transfer(所有权转移) move clone copy References and Borrowing(引用和借用) Mutable References(可变引用) Dangling References(悬垂引用) what's ownership? 常见的高级语言都有自己的 Garbage Collection(GC)机制来管理程序运行的内存,例如 Java.Go 等.而 Rust 引入了一种全

  • Rust你不认识的所有权

    在Rust中是没有内存垃圾回收机制(GC)的,那Rust是如何保障内存安全的呢?这就引出了“所有权”这个概念. 我们看下下面这段伪代码 let s = "helloString"; t = s; print(s); 在之前我们学习的语言中,比如C语言,对于上述伪代码的执行结果应该是正常打印"helloString" 的内容,但是在Rust中,执行上述代码时,会出现如下提示 ------ 增加所有权返回内容: 而产生这个结果的原因就是触发了Rust语言中所有权机制:

  • 关于Rust 使用 dotenv 来设置环境变量的问题

    Rust 语言是一种高效.可靠的通用高级语言.其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言. Rust语言的特点 高性能 - Rust 速度惊人且内存利用率极高.由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成. 可靠性 - Rust 丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误. 生产力 - Rust 拥有出色的文档.友好的编译器和清晰的错误提示

  • 如何使用rust实现简单的单链表

    目录 前言 1.链表节点的定义 2.链表的定义 3.实现从链表头部插入节点的prepend方法 4.为链表实现Display trait定制链表的打印显示 5.为链表实现翻转链表功能的reverse方法 注意事项 总结 前言 作为初学者,在掌握了rust的基本语法和所有权机制,尝试写一下常见数据结构和算法,目标是为了更好的理解rust的所有权机制. 受限于个人目前对rust仍处于入门阶段,因此本文代码实现不一定是最合适的,甚至可能存在问题. 今天的目标是用rust实现一个简单的单链表Linked

  • 关于rust的模块引入问题

    目录 Rust语言的特点 Rust的应用 worker.rs文件,简单看一下 student.rs看一下 teacher.rs看一下 第一部分是一个绝对路径的引入 第二部分是相对路径的引入 第三部分看一下use关键词 国庆第一次学习,真是太罪恶了,555 主要还是看这个官网学的,这一部分对应的是官网上那个教程的第七章,写的实在是让人有点费解,所以我这边自己写一下,当然范围限制在第七章,因为我暂时只是看到哪里 Rust 语言是一种高效.可靠的通用高级语言.其高效不仅限于开发效率,它的执行效率也是令

  • C++的替代:微软如何使用rust?

    微软拥有世界上最大的C/C++代码库之一.从Windows.Office到Azure云,微软的所有核心产品都在该代码库上运行.但因为C++不是内存安全的语言,代码库中自然频频出现内存漏洞,大量的时间被耗费在修补漏洞上. 微软自去年开始寻找用以替代的编程语言来解决内存安全问题,寻找终有所得--微软开始尝试使用Rust,并在一些情境下将其集成进代码库中.Rust是一种相对较新的编程语言,具有与C和C++相同的底层性能,并具备现代编程语言应有的功能集. 微软认为Rust颇具潜力,本文就将介绍微软将其用

  • C和Java没那么香了,Serverless时代Rust即将称王?

    目录 高并发模式初探 C语言的高并发案例 Java的高并发实现 Go的高并发实现 Rust的高并发实现 总结 高并发模式初探 在这个高并发时代最重要的设计模式无疑是生产者.消费者模式,比如著名的消息队列kafka其实就是一个生产者消费者模式的典型实现.其实生产者消费者问题,也就是有限缓冲问题,可以用以下场景进行简要描述,生产者生成一定量的产品放到库房,并不断重复此过程:与此同时,消费者也在缓冲区消耗这些数据,但由于库房大小有限,所以生产者和消费者之间步调协调,生产者不会在库房满的情况放入端口,消

  • Rust 中的文件操作示例详解

    目录 文件路径 文件创建和删除 目录创建和删除 文件创建和删除 文件读取和写入 文件打开 文件读取 文件写入 相关资料 文件路径 想要打开或者创建一个文件,首先要指定文件的路径. Rust 中的路径操作是跨平台的,std::path 模块提供的了两个用于描述路径的类型: PathBuf – 具有所有权并且可被修改,类似于 String. Path – 路径切片,类似于 str. 示例: use std::path::Path; use std::path::PathBuf; fn main()

  • Rust中的Struct使用示例详解

    Structs是RUST中比较常见的自定义类型之一,又可以分为StructStruct,TupleStruct,UnitStruct三个类型,结合泛型.Trait限定.属性.可见性可以衍生出很丰富的类型. 结构体 1.定义 pub struct User { user_id : u32, user_name: String, is_vip : bool, } 2.实例化这里初始化必须全部给所有的成员赋值,不像C++,可以单独初始化某个值 let user : User = User { user

  • 解析rust中的struct

    目录 定义struct 实例化struct 取得struct里面的某个值 struct作为函数的放回值 字段初始化简写 struct更新语法 tuple struct Unit-Like Struct(没有任何字段) struct数据的所有权 什么事struct struct的方法 定义方法 ​​​​​​​​​​​​​​方法调用的运算符 关联函数 多个impl块 定义struct 使用struct关键字,并为整个struct命名 在花括号内,为所有字段(field)定义名称和类型 struct

随机推荐