【rust】| 06——语言特性 | 所有权

这篇具有很好参考价值的文章主要介绍了【rust】| 06——语言特性 | 所有权。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录
【rust】| 00——开发环境搭建
【rust】| 01——编译并运行第一个rust程序
【rust】| 02——语法基础 | 变量(不可变?)和常量
【rust】| 03——语法基础 | 数据类型
【rust】| 04——语法基础 | 函数
【rust】| 05——语法基础 | 流程控制
【rust】| 06——语言特性 | 所有权

1. 所有权的概念

 所有权是Rust语言中一个关键的特性。它是一种内存管理规则(机制)。它通过这个规则(即所有权系统)结合编译器对代码进行检查 从而确保内存安全。
 在其他语言如C/C++ 等 都有自己的内存管理方式。C/C++需要我们显式(手动)处理所用的内存(申请、释放) 如果处理不当会造成很严重的内存安全问题。而Rust中这一特性很好的可以帮我们确保内存安全性。

2. 所有权的规则

1、每个值都对应一个变量 owner
2、一个值只能有一个 owner
3、有作用域,当owner超出作用域 值会被销毁 (这个变量有生命周期 在作用域内)

3. 变量的作用域

Rust中变量的作用域和其他语言类型。比如函数体内的 变量(局部变量) 它的作用域在 函数大括号之间 生命周期也是这么短。
【rust】| 06——语言特性 | 所有权
可以看到 超过范围销毁了。 对应所有权规则的最后一条。owner 就是这个值藏在暗处的变量名。 它超过变量作用域会消失。Rust内部在超出后 会掉清理函数 drop
清理变量占用的内存。

4. 所有权的移动/克隆

4.1 移动

Rust中的移动 类似浅拷贝 但有细节之处。
我们通过代码例子去理解

1、变量赋值操作

【rust】| 06——语言特性 | 所有权
分析:
  1、整型变量赋值 变量a 复制到了 变量b
  2、字符串赋值 变量s1 复制到了 变量s2
  我们可以看到 两种不同的类型 操作几乎是一样的。 整型它只是一个数字 再怎么复制占用的大小就那么多 无关紧要。可是当是一个很大的字符串 复制给另一个变量 那所占用的大小(很大*2) 这样的操作 太占用大小 咋的一个字符串准备要我命啊。是不是和其他语言复制操作很类似。
  但是在 Rust中 复制的操作 还是有细微差别的 我们深入了解下rust下 具体复制的具体过程

细看 字符串变量的定义及复制到其他变量的过程

【rust】| 06——语言特性 | 所有权
可以看到 字符串变量的内容 hello 存储在堆上 而 定义的变量 S1 只保存了 指向堆上内容的指针、长度和容量这三个 这些内容存储在栈上。并没有将 字符串内容也保存。
下面我们看 S1内容复制给S2 是怎样的
【rust】| 06——语言特性 | 所有权
可以看到 S1 复制到 S2 也只是复制了 指针、长度、容量三件套。不重复复制堆上内容。这样的情况下S1 S2是不是 占用栈大小很少。

如果S1 S2把数据一起保存呢
【rust】| 06——语言特性 | 所有权
可以看到 全保存过来 每个变量 都这样完全复制 那栈吃不消。当内容很大时 是不是 一个赋值操作直接给 栈空间 用完 干废掉啦。

通过上面图我们可以看到 rust中 变量保存了指向内容的指针等。 S1 和S2 中的指针都指向了 数据内容。我们知道所有权规则之一 变量超出作用域 会没了。那么当S1和S2 超出作用域 会尝试释放 因为它两指向一个地址那么 两次释放是不是会出大问题呢。也称为 双重释放错误。
当然 rust中也会想到这种错误 所以它会避免啦。
【rust】| 06——语言特性 | 所有权

【rust】| 06——语言特性 | 所有权
在Rust中 执行完 S2=S1这样的操作 S1已经变得无效啦 所以不会再存在上面双重释放的隐患了。
其实 Rust中S2 = S1 的操作类似浅拷贝 只拷贝了指针长度容量。但是rust 中超出范围 让其消失的规则 即S1 无效啦的操作 我们把这样称为 移动

4.2 克隆 clone

Rust中 我们把类似 深拷贝(把数据内容一起复制)的操作
称为克隆 clone。
【rust】| 06——语言特性 | 所有权

4.3 copy

前面学习完 移动和克隆 我们理解到 在Rust中 通过变量给变量赋值的操作 如果直接赋值 S2 = S1 这种 类似于浅拷贝 而且S1会消失 没有拷贝在堆上的内容 而 通过克隆 s2=s1.clone() 这种 类似深拷贝的操作 这样S1还活着。 下面我们通过例子理解COPY
【rust】| 06——语言特性 | 所有权
为什么x 还能用? 因为X是整型 编译器编译时 知道它的大小 将内容全部存储在栈中。也可以说整型具有copy特性 所以才会存在栈上。字符串型 大小我们不确定因为不知道后面会不会 改变。 在这种情况下 深浅拷贝(克隆)没区别。

具有copy特性的类型

  • 所以整型
  • 布尔类型
  • 所以浮点型
  • 字符型 char
  • 元组(元素类型为以上几种)

5. 所有权的转移

函数和返回值 都可以转移属性

5.1 函数转移

通过函数入参 将变量移动/复制 和变量移动/复制一样的
通过例子学习

【rust】| 06——语言特性 | 所有权
通过这个可以看到 和变量是一样的

5.2 返回值转移

通过返回值 转移

【rust】| 06——语言特性 | 所有权

6. 引用和借用

有些场景我们只需要使用值 而且会多次使用 一个变量本身具有所有权 多次使用需要移动来移动去 好麻烦 有没有办法不要所有权 那就是通过引用的方式。

6.1 引用

引用: 使用值而不转移(获取)所有权
引用没有所有权

引用通过地址来访问存储在该地址的数据

【rust】| 06——语言特性 | 所有权
【rust】| 06——语言特性 | 所有权
我们可以看到上面 函数定义入参 s: &sring 它的含义 我们创建了一个引用 来接收传入的实参引用 也称为 借用

6.2 借用

借用 是创建引用的动作
借用是 不能修改引用的值

借用 顾名思义 我借了别人东西 我要原模原样还给人家 不能说 搞坏了还吧
上demo
【rust】| 06——语言特性 | 所有权

可以看到 引用 和 默认情况下的变量 一样是不可变的

6.3 可变引用

引用默认情况下 不可修改内容 和默认变量一样

上面代码因为我们定义了不可变的变量等 那我们给他给加上可变的标志 是不是就可以变啦 是的

【rust】| 06——语言特性 | 所有权
可以看到 定义变量 函数入参等 都修改为 可变的 少一个都不行 否者会报错 既然要该那么都得是可变属性哦

可变引用的约束

1、一个变量只能有一个可变引用

防止多个引用同时对一个值 修改

【rust】| 06——语言特性 | 所有权

6.4 空引用

类似空指针。
在rust中 编译器会保证不会存在空引用。
编译器检测过程
【rust】| 06——语言特性 | 所有权
但我们又想用 函数内局部变量怎么办
前面我们学习了 返回值可以转移所有权 那么我们返回 变量是不是就可以了
【rust】| 06——语言特性 | 所有权

7. 切片

切片也是一种引用,切片没有所有权。
切片:对一个集合(元组 字符串) 引用其部分连续元素的操作
注: 切片不能对整个切 只能连续的某部分 是有范围的

7.1 字符串切片

【rust】| 06——语言特性 | 所有权
我们看看切片数据的内部存储结构是怎样的
【rust】| 06——语言特性 | 所有权
可以看到切片只存储了 起始位置的指针 和切的长度

还有一种字符串类型 &str 它指向二进制文件 这个字符串不可变
let s=“awdada”; // s是 &str类型

7.2 其他切片

和字符串切片类似 只是切的对象换了 可以切好多
比如 切数组 引用数组中一部分元素
【rust】| 06——语言特性 | 所有权

7.3 切片的范围

我们通过前面知道切片是如何创建
知道了 [ ] 方括号之间需要填切片的范围
那么当我们想切片的起始位置从0开始 除了 [0…x] 还有其他的表达方式

1、切片索引从0开始 的表达方式

【rust】| 06——语言特性 | 所有权

同样的 结尾位置 也可以 用省略 表达

2、切片索引 到末尾 的表达方式

【rust】| 06——语言特性 | 所有权

3、表示整个 同理 省略起始和结尾值 [ . . ]

7.4 切片做函数参数

【rust】| 06——语言特性 | 所有权文章来源地址https://www.toymoban.com/news/detail-443607.html

到了这里,关于【rust】| 06——语言特性 | 所有权的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Rust之所有权

    程序需要管理自己在运行时使用的计算机内部空间。Rust语言采用包含特定规则的所有权系统来管理内存,这套规则允许编译器在编译的过程中执行检查工作,而不会产生任何的运行时开销。 Rust中的每一个值都有一个对应的变量作为它的所有者; 在同一时间内,值有且仅有一

    2024年02月16日
    浏览(47)
  • Rust-所有权(ownership)

    Rust入门学习系列-Rust 的核心功能(之一)是 所有权(ownership)。引入这个概念是为了更好的管理计算机的内存。下面篇幅让我们来研究下这个功能有什么神奇之处。 常见的编程语言中计算机内存管理方式: Java:Java使用Java虚拟机(JVM)来管理计算机内存。JVM有一个垃圾回收

    2024年02月19日
    浏览(39)
  • Rust核心功能之一(所有权)

    目录 1、什么是所有权? 1.1 所有权规则  1.2 变量作用域 1.3 String 类型 1.4 内存与分配 变量与数据交互的方式(一):移动 变量与数据交互的方式(二):克隆 只在栈上的数据:拷贝 1.5 所有权与函数 1.6 返回值与作用域 所有权(系统)是 Rust 最为与众不同的特性,对语言的

    2024年02月04日
    浏览(43)
  • Rust-所有权和移动语义

    拿C语言的代码来打个比方。我们可能会在堆上创建一个对象,然后使用一个指针来管理这个对象: 接下来,我们可能需要使用这个对象: 然而,这段代码之后,谁能猜得到,指针p指向的对象究竟发生了什么?它是否被修改过了?它还存在吗,是否已经被释放?是否有另外一个指

    2024年01月18日
    浏览(39)
  • rust学习——栈、堆、所有权

    栈和堆是编程语言最核心的数据结构,但是在很多语言中,你并不需要深入了解栈与堆。 但对于 Rust 这样的系统编程语言,值是位于栈上还是堆上非常重要, 因为这会影响程序的行为和性能。 栈和堆的核心目标就是为程序在运行时提供可供使用的内存空间。 栈 栈按照顺序存

    2024年02月07日
    浏览(72)
  • 【Rust】Rust学习 第四章认识所有权

    所有权(系统)是 Rust 最为与众不同的特性,它让 Rust 无需垃圾回收(garbage collector)即可保障内存安全。因此,理解 Rust 中所有权如何工作是十分重要的。 4.1 所有权 所有运行的程序都必须管理其使用计算机内存的方式。一些语言中具有垃圾回收机制,在程序运行时不断地

    2024年02月13日
    浏览(53)
  • 30天拿下Rust之所有权

    概述         在编程语言的世界中,Rust凭借其独特的所有权机制脱颖而出,为开发者提供了一种新颖而强大的工具来防止内存错误。这一特性不仅确保了代码的安全性,还极大地提升了程序的性能。在Rust中,所有权是一种编译时检查机制,用于追踪哪些内存或资源何时可

    2024年03月08日
    浏览(39)
  • Rust语法:所有权&引用&生命周期

    垃圾回收管理内存 Python,Java这类语言在管理内存时引用了一种叫做垃圾回收的技术,这种技术会为每个变量设置一个引用计数器(reference counter),来统计每个对象的引用次数。 一旦某个对象的引用数为0,垃圾回收器就会择取一个时机将其所占用的空间回收。 以Python为例子

    2024年02月12日
    浏览(55)
  • Rust 基础入门 —— 2.3.所有权和借用

    Rust 的最主要光芒: 内存安全 。 实现方式: 所有权系统 。 因为我们这里实际讲述的内容是关于 内存安全的,所以我们最好先复习一下内存的知识。 然后我们,需要理解的就只有所有权概念,以及为了开发便利,进一步引出的引用借用概念。 内存作为存储程序运行时数据

    2024年02月12日
    浏览(37)
  • 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念

    【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 本章节将讲解 Rust 独有的概念(所有权)。所有权是 Rust 最独特的特性,它使得 Rust 能够

    2024年02月10日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包