Rust之所有权

1、所有权的概念:

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

(1)、所有权规则:

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

(2)、变量的作用域:

作用域是指一个对象在程序中的有效范围。
变量的有效范围说明:

{//S未被声明,在这里还不可用let s = "hello";//从这里开始S变得可用//执行与S相关的操作
}//作用域到这儿结束,变量S再次不可用

2、String类型:

String类型的数据存放在堆上,是一个可变的字符串类型。Rust在变量结束的地方会自动调用drop函数,String类型的作者在drop函数中编写了自动释放内存的程序。
注意:任何简单的标量的组合类型都是可以Copy的,任何需要分配内存或某种资源的类型都不会是Copy的。下面是一些拥有Copy这种trait的类型:

  • 所有的整数类型;
  • 仅拥有两种值的布尔类型;
  • 字符类型;
  • 所有的浮点类型;
  • 如果元组所包含的所有字段的类型都是Copy的,那么这个元组也是Copy的。

3、所有权与函数:

将值传递给函数在语义上类似于对变量进行赋值。将变量传递给函数将会触发移动或复制,就像赋值语句一样。

fn main()
{let s = String::from("hello");//变量s进入作用域takes_owership(s);//s的值被移动进了函数//s的值在这里不再有效let x = 5;//x进入作用域make_copy(x);//x的值被传递进了函数//由于i32是Copy的,所以在这儿依旧可以使用x
}//x的值首先离开作用域,随后是s
//由于s已经发生了移动,所以不会发生什么情况
fn takes_owership(some_string:String){//s进入作用域println!("{}",some_string);
}//some_string在这里离开作用域,drop函数被自动调用
//some_string所占用的内存被释放
fn make_copy(some_integer:i32){//some_integer进入作用域println!("{}",some_integer);
}//some_integer在这里离开作用域,没有什么发生

4、返回值与作用域:

函数在返回值的过程中也会发生所有权的转移。
变量所有权的转移总会遵循相同的模式:将一个变量赋值给另一个变量时就会转移所有权。当一个持有堆数据的变量离开作用域时,它的数据就会被drop清理回收,除非这些数据的所有权转移到了另一个变量上。

5、引用与借用:

引用是指在不获取所有权的前提下使用某个变量的值。
示例:

fn main(){let s1 = String::from("hello");let len = calculate_length(&s1);println!("The length of '{}'is {}.",s1,len);
}
fn calculate_length -> usize{s.len()
}

在调用calculate_length函数时使用了&s1作为参数,并且在该函数的定义中,使用&String替代了String。
其中&代表的就是引用的语义。
由于引用并不持有值的所有权,所以当引用离开当前作用域的时候,它指向的值也不会被丢弃,同样也不能对引用值进行更改。
这种通过引用传递参数给函数的方法也被称为借用。

6、可变引用:

将变量声明为mut s,再使用&mut s给函数传递一个可变引用,并将函数签名改为some_string:&mut String来使其接收一个可变引用作为参数。
可变引用在使用上有一个限制:对于特定作用域中的特定数值来说,一次只能声明一个可变引用。以下示例违背了这条规则:

let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;

Rust中的这一限定性规则可以帮助在编译时避免数据竞争。数据竞争与竞态条件十分相似,它会在满足以下三种情况时发生:

  1. 两个或两个以上的指针同时访问同一空间;
  2. 其中至少有一个指针会向空间中写入数据;
  3. 没有同步数据访问的机制。
    数据竞争会导致未定义行为,这些未定义行为会使得出现的bug难以被修复和诊断。

7、悬垂引用:

悬垂指针指向曾经存在的某处内存地址,但该内存已近被释放甚至是被重新分配另作他用了。

8、切片:

切片允许我们引用集合中某一段连续的元素序列,而不是整个集合。

(1)、字符串切片:

字符串切片是指向String对象中某个连续部分的引用,它使用方式如下:

let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];

使用方括号中指定切片的范围区间[starting_index..ending_index],其中starting_index是切片起始位置的索引值,ending_index是切片终止位置的下一个索引值。切片数据结构在内部存储了指向起始位置的引用和一个描述切片长度的字段,这个描述切片长度的字段等价于ending_index减去starting_index
注:当范围是从第一个元素开始时,可以省略两个点号之前的值;当切片包含String中的最后一个字节时,可以省略双点号之后的值。

(2)、其它类型的切片:

字符串切片是专门用来处理字符串的,除此之外,Rust还存在其他更为通用的切片类型,以数组为例:

let a = [1,2,3,4,5];
let slice = &a[1..3];

这与字符串切片的工作机制完全一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前端知识】React 基础巩固(三十)——CSS编写方式

React 基础巩固(三十)——CSS编写方式 1.内联样式 Style 接受一个采用小驼峰命名属性的JS对象,而不是CSS字符串 可以引用state中的状态来设置相关的样式 优点:样式之间不会有冲突;可以动态获取当前state中的状态 缺点:需要使用…

微信小程序——页面跳转方法和场景用法总结

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

Arduino 与 Unity3D TCP通信

一、通过传输流的方式 #include <WiFi.h>#define LED_PIN 5 const char * ssid "Daschow2021"; const char * password "daschow2021"; void setup() {Serial.begin(9600);//连接WiFiWiFi.begin(ssid,password);Serial.print("正在连接Wifi&…

linux麒麟系统二级等保【三权分立策略】

目录 三权分立策略 一、系统管理员 二、审计管理员 三、安全管理员 三权分立策略 "建议创建管理、操作、审计三类独立权限账号&#xff0c;支持三权分立机制。参考配置&#xff1a; 管理账号&#xff08;root&#xff09;&#xff1a;拥有所有操作权限&#xff1b;…

如何理解spring cloud 和 spring cloud Alibaba

Spring Cloud是一个基于Spring Framework构建的用于开发和构建分布式系统的开源框架。它提供了一系列的工具和组件&#xff0c;用于帮助开发者快速构建、部署和管理微服务架构。Spring Cloud提供了包括服务发现、配置管理、负载均衡、断路器等在内的众多功能。 Spring Cloud A…

第四十三天

●<template>&#xff1a;每个vue文件中最多可以包含一个&#xff0c;语块包裹的内容内容会被提取&#xff0c;编译成js渲染函数&#xff0c;并附在导出的组件上作为其render选项。 ●<script>​&#xff1a;每个 vue 文件最多可以包含一个 script>块(使用 <…

【JVM】JVM执行流程 JVM类加载 垃圾回收机制等

目录 &#x1f337;1、JVM是什么&#xff1f; &#x1f337;2、JVM的执行流程&#xff08;能够描述数据区5部分&#xff09; &#x1f337;3、JVM类加载过程 &#x1f337;4、双亲委派机制&#xff1a;描述类加载的过程 问题1&#xff1a;类加载器 问题2&#xff1a;什么…

Ubuntu Linux中hostname`命令

当然&#xff0c;让我们将关于在Ubuntu Linux中理解hostname的知识转化为列表形式&#xff1a; 参考&#xff1a; https://www.howtouseubuntu.com/network/change-hostname-in-ubuntu-linux/ 定义&#xff1a;hostname是Ubuntu&#xff08;以及其他Linux发行版&#xff09;中…

最优贸易(记忆化搜索)

题目链接&#xff1a;[NOIP2009 提高组] 最优贸易 - 洛谷 思路&#xff1a;这道题的标签是SPFA&#xff0c;但是我觉得这道题可以用记忆化搜索&#xff0c;用两组dfs&#xff0c;将从1到 i点道路上的最小值都存进min数组&#xff0c;将i 到n点的最大值存进max组&#xff0c;最后…

支付宝原生小程序组件与父级传递数据(微信小程序基本一样)

1. 声明组件 在对应的目录下,右击点击 新建小程序,之后会生成对应的文件 2. 子组件 Component({data: {colorList: [#165FF6, #3D16F6,

一元多项式的表示及相加

实现思路&#xff1a; 通过链表实现&#xff0c;会更为简单直观。用链表中的每个结点表示多项式中的每一项&#xff0c;多项式每一项都是由数据域&#xff08;包含系数和指数&#xff09;和指针域构成的&#xff0c;所以在定义表示结点的结构体时&#xff0c;可如下所示进行定义…

FFMPEG android mac 编译 支持DASH/OPENSSL问题汇总

一 下载源码 FFMPEG https://github.com/FFmpeg/FFmpeg/tree/release/4.3 二 编写脚本 支持https 就必须添加open SSL 的编译 具体可以查看我的另一个关于open SSL 的 然后我们配置的一些路径 涉及 ndk 的一定要查看你用的ndk 版本 是否存在这些路径这是第一步 然后如果支…

python爬虫入门

基础回顾 使用函数, 先导入, 直接点方法名使用 import math m math.log10(100) print(m)python 交互模式 input输入示例 age int(input("请输入年龄")) age 1 print(age)if else 的使用 和java一样, 只是不加括号, else if 阉割成了 elif 与或非 java : &am…

网络中的一些概念对比

HTTP与HTTPS 从安全性和效率性进行阐述&#xff1a; 对于HTTP HTTP默认端口是80 HTTP是明文传输&#xff0c;数据以纯文本、明文形式在网络上传输&#xff0c;容易受到黑客的攻击和数据窃取。 对于HTTPS HTTPS默认端口是443 HTTPS用的是SSL或者TLS协议对数据进行加密&am…

No3: 学习过程中故障成长积累

文章目录 故障积累1、编码错误导致 故障积累1、编码错误导致

5.2 Bootstrap 过渡效果(Transition)插件

文章目录 Bootstrap 过渡效果&#xff08;Transition&#xff09;插件使用案例 Bootstrap 过渡效果&#xff08;Transition&#xff09;插件 过渡效果&#xff08;Transition&#xff09;插件提供了简单的过渡效果。 注意&#xff1a;如果您想要单独引用该插件的功能&#xff0…

Typescript:类的装饰器

装饰器 装饰器为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式 装饰器是一种特殊类型的声明&#xff0c;它能够被附加到类声明&#xff0c;方法&#xff0c; 访问符&#xff0c;属性或参数上。 装饰器使用 expression这种形式&#xff0c;expression求值后必…

【ACM】—蓝桥杯大一暑期集训Day5

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前正在学习C/C、Java、算法等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&#xff…

Qt6 Qt Quick UI原型学习QML第五篇

文章目录 效果QML语法父文件 MyQML.qmlQML语法子文件 TLineEditV1.qmlQML语法子文件 TTextEdit.qml 效果 QML语法父文件 MyQML.qml import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12Window {id: windowvisible: truewidth: 600height: 600title:…

Linux系统进程概念详解

这里写目录标题 冯诺依曼体系结构操作系统(Operator System)1.概念2.目的3.管理4.系统调用和库函数概念 进程1.概念2.描述进程-PCB3.查看进程4.通过系统调用获取进程标示符5.通过系统调用创建进程-fork 进程状态1.Linux内核源代码2.进程状态查看 进程优先级1.基本概念2.查看系统…