18.所有权

因为变量要负责释放它们拥有的资源,所以资源只能拥有一个所有者。这也防止了资源的重复释放。注意并非所有变量都拥有资源(例如引用)。

在进行赋值(let a = b)或通过值来传递函数参数(foo(a))的时候,资源的所有权(ownership)会发生转移。按照 Rust 的规范,这被称为资源的移动(move)。

在移动资源之后,原来的所有者不能再被使用,这可避免悬挂指针(dangling pointer)的产生。

内存分为两大类:栈(stack) 和 堆(heap)

它是一种 后进先出 的机制,类似我们日常的落盘子,只能一个一个向上方,然后从最上面拿一个盘子。一个变量要放到栈上,那么它的大小在编译时就要明确。i32 类型的变量,它就占用 4 个字节。Rust 中可以放到栈上的数据类型,他们的大小都是固定的。如果是字符串,在运行时才会赋值的变量,在编译期的时候大小是未知或不确定的。所以字符串类型存储在堆上。

用于编译时大小未知或不确定的,只有运行时才能确定的数据。在堆上存储一些动态类型的数据。堆是不受系统管理的,是用户自己管理的,也增加了内存溢出的风险。

所有权

所有权就是值一个东西归属谁。Rust 中一个变量对应一个值,变量就称为这个值得所有者。

let name="从0到Go语言微服务架构师";

这句话的意思就是,”从 0 到 Go 语言微服务架构师” 这个值所在内存块由变量 name 所有。

Rust 中,只能由一个所有者,不允许两个同时指向同一块内存区域。变量必须指向不同的内存区域。

转让所有权

类似我们人类把一个东西送人或丢弃。

以下几种方式转让所有权:

  1. 把一个变量赋值给另一个变量。
fn main() {// 栈分配的整型let a = 88;// 将 `a` *复制*到 `b`——不存在资源移动let b = a;// 两个值各自都可以使用println!("a {}, and b {}", a, b);let v1 = vec!["Go语言极简一本通","Go语言微服务架构核心22讲","从0到Go语言微服务架构师"];let v2 =v1;println!("{:?}",v1);
}报错如下:
error[E0382]: borrow of moved value: `v1`
let v1 = vec!["Go语言极简一本通","Go语言微服务架构核心22讲","从0到Go语言微服务架构师"];
| -- move occurs because `v1` has type `Vec<&str>`, which does not implement the `Copy` trait
9 | let v2 =v1;
| -- value moved here
10 | println!("{:?}",v1);
| ^^ value borrowed here after move
|
  • v1 拥有堆上数据的所有权。(每次只能有一个变量对堆上数据有所有权)
  • v2=v1 v2 拥有了堆上数据的所有权。
  • v1 已经没有对数据的所有权了,所以再使用 v1 会报错。
  • 如果 Rust 检查到 2 个变量同时拥有堆上内存的所有权。会报错如上。
  1. 把变量传递给函数参数。
fn show(v:Vec<&str>){println!("v {:?}",v)
}
fn main() {let studyList = vec!["Go语言极简一本通","Go语言微服务架构核心22讲","从0到Go语言微服务架构师"];//studyList 拥有堆上数据管理权let studyList2 = studyList;// studyList 将所有权转义给了 studyList2show(studyList2);// studyList2 将所有权转让给参数 v,studyList2 不再可用。println!("studyList2 {:?}",studyList2);//studyList2 已经不可用。
}error[E0382]: borrow of moved value: `studyList2`
| let studyList2 = studyList; // studyList 将所有权转义给了 studyList2
| ---------- move occurs because `studyList2` has type `Vec<&str>`, which does not implement the `Copy` trait
| show(studyList2); // studyList2 将所有权转让给参数 v,studyList2 不再可用。
| ---------- value moved here
| println!("studyList2 {:?}",studyList2);//studyList2 已经不可用。
| ^^^^^^^^^^ value borrowed here after move
  1. 函数中的返回值。
fn show2(v:Vec<&str>) -> Vec<&str>{println!("v {:?}",v);return v;
}fn main() {let studyList3 = vec!["Go语言极简一本通","Go语言微服务架构核心22讲","从0到Go语言微服务架构师"];let studyList4 = studyList3;let result = show2(studyList4);println!("result {:?}",result);//输出 result ["Go语言极简一本通", "Go语言微服务架构核心22讲", "从0到Go语言微服务架构师"]
}

基础数据类型与所有权

所有权只会发生在堆上分配的数据,基础数据类型(整型,浮点型,布尔,字符)存储在栈上,所以没有所有权的概念。基础类型可以认为是值拷贝,在内存上另外的地方,存储和复制来的数据,然后让新的变量指向它。

let a = 88;
let b = a;
println!("a {}, and b {}", a, b);

总结

赋值并不是唯一涉及移动的操作。值在作为参数传递或从函数返回时也会被移动:

rust-所有权和移动相关推荐

  1. Rust学习笔记(13)——struct、Option和Box组合应用实现单向链表

    前面深入学习了struct.Option和Box的所有权约束及各种场景的使用,现在用struct.Option和Box组合来实现一个单向链表,并实现链表常见的头部插入.删除,尾部插入.删除,中间插入. ...

  2. Rust 和Erlang的对比

    \ 本文要点: \\ Erlang提供轻量级流程.不变性.位置透明的分布式.消息传递.监督行为以及许多其他高级动态功能,这些特性使其成为容错.高可用性和可扩展系统的理想之选.\\t 不幸的是,在执行X ...

  3. 6月 CSDN 创作者之夜:获奖名单公布

    在5月份,各位创作者都在坚持输出文章,为了感谢各位创作者的支持,我们也会其中一些优质博主进行颁奖,文章本期获奖名单从多个角度进行评选,有的是通过活动获得,有的是通过文章上榜获得,具体奖项有新人奖.实力 ...

  4. rust的所有权和生命周期问题,借用问题

    我们知道所有权系统是rust语言内存安全的重要原因之一. 举个例子,比如main函数里面声明一个动态数组arr,并把这个数组作为参数传到另一个函数中. (要知道vector或者int *p=new i ...

  5. 年前最后一项技能树 Rust ,攻碉堡 ing (Bilibili 视频整理)

    前言 我自己的语言语言学习树 最新的新闻 最近的新闻,Rust 审核团队,集体辞职抗议, 还是linux 社区的 linus 牛皮,镇得住场子不要慌,咱们是在linux 社区混的,影响不大,该学还是得 ...

  6. [译]使用 Rust 开发一个简单的 Web 应用,第 4 部分 —— CLI 选项解析

    原文地址:A Simple Web App in Rust, Part 4 -- CLI Option Parsing 原文作者:Joel's Journal 译文出自:掘金翻译计划 本文永久链接:g ...

  7. rust go java 性能_Java,Go和Rust之间的比较 - Dexter

    这是Java,Go和Rust之间的比较.这不是基准测试,而是关于:可执行文件大小.内存使用.CPU使用率.运行时要求之间的比较,当然还有一个小的基准测试,可以每秒获取一些请求. 测试三个Web服务的存 ...

  8. 彷徨编程十几年,终于盯上 Rust

    现有的编程语言非常多,我们都习惯了要在性能.表达力和内存安全之间取舍,直到 Rust 横空出世. 对于 Rust 这个新语言,很多人可能都听过,但是没用过.实际上,早从 16 年起,Rust 已经连续 ...

  9. C++和Rust_后端程序员一定要看的语言大比拼:Java vs. Go vs. Rust

    这是Java,Go和Rust之间的比较.这不是基准测试,更多是对可执行文件大小.内存使用率.CPU使用率.运行时要求等的比较,当然还有一个小的基准测试,可以看到每秒处理的请求数量,我将尝试对这些数字进 ...

  10. java时间比较大小_Go、Java 和 Rust 的比较:得出了挺多结论

    点击上方蓝色"火丁笔记"关注我们,设个星标,每天学习全栈知识 最近这几年,Go.Rust 收到越来越多的关注,特别是 Go,在国内挺受欢迎的,很多大公司都采用它.而 Rust,作为 ...

最新文章

  1. angular5 清除定时器
  2. IOS 浏览器端overflow:scroll overflow:auto元素无法滑动bug解决方法整理
  3. ubuntu切换python,以及切换python后相关包的管理
  4. 在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射
  5. 美国计算机科学专业申请要求,美国计算机科学专业申请条件
  6. namespace! 报错
  7. 2018/01/08JAVA 基础 / 接口与继承:[Q]:若父类Hero提供了一个有参的构造方法,但是没有提供无参的构造方法。子类应该怎么处理?...
  8. 别太相信自己,总有一种诈骗戳中你的刚需
  9. RAM调优之日志分析
  10. Python 命令行之旅:深入 argparse(二)
  11. OpenCV medianBlur、GaussianBlur和bilateralFilter (中值滤波、高斯滤波、双边滤波)
  12. m1136能支持哪些服务器,实测惠普M1136无线一体机,成就精英效率!
  13. 决策树模型回归可视化分析_基于Blank Friday商店销售数据分析构建回归模型
  14. Spring源码分析总结(二)-Spring AOP 解析aop:aspectj-autoproxy
  15. 为什么我们对工作缺乏责任心
  16. android+获取相册列表,android 获取相册列表的实现(一)
  17. VUE+element 上传视频
  18. Python变量与字符串操作
  19. ReentrantLock入门级
  20. 传奇服务器脚本文件在哪个文件夹,传奇服务端各个文件夹目录结构详细说明表...

热门文章

  1. 工具篇:gatling
  2. conda显示虚拟环境_conda虚拟环境
  3. 用java搭建一个分布式服务器(一)
  4. 最新2022阿迪达斯AI面试真题题库
  5. 百家号怎么写爆文?百家号写爆文有哪些技巧
  6. 使用wpf引入资源文件,RichTestBox加载rtf文件
  7. Python爬虫入门案例教学:批量爬取彼岸桌面4K超清美女壁纸
  8. 阿里-应届生面试求职基础题以及答案(2)
  9. js中clientX,offsetX,pageX,screenX图示
  10. 基于MATLAB GUI的数字图像处理系统