Rust-变量

Rust的变量必须先声明后使用。对于局部变量,最常见的声明语法为:

let variable:i32 =100;

与传统的C/C++语言相比,Rust的变量声明语法不同。这样设计主要有以下几个方面的考虑。

  1. 语法分析更容易
    从语法分析的角度来说,Rust的变量声明语法比C/C++语言的简单,局部变量声明一定是以关键字let开头,类型一定是跟在冒号:的后面。语法歧义更少,语法分析器更容易编写。

  2. 方便引入类型推导功能
    Rust的变量声明的一个重要特点是:要声明的变量前置,对它的类型描述后置。这也是吸取了其他语言的教训后的结果。

    因为在变量声明语句中,最重要的是变量本身,而类型其实是个附属的额外描述,并非必不可少的部分。

    如果我们可以通过上下文环境由编译器自动分析出这个变量的类型,那么这个类型描述完全可以省略不写。

    Rust一开始的设计就考虑了类型自动推导功能,因此类型后置的语法更合适。

  3. 模式解构
    let语句不光是局部变量声明语句,而且具有pattern destructure(模式解构)的功能。

实际上,包括C++/C#/Java等传统编程语言都开始逐步引入这种声明语法,目的是相似的。

Rust中声明变量缺省是“只读”的,比如如下程序:
在这里插入图片描述
如果我们需要让变量是可写的,那么需要使用mut关键字:
在这里插入图片描述
let语句在此处引入了一个模式解构,我们不能把let mut视为一个组合,而应该将mut x视为一个组合。

mut x是一个“模式”,我们还可以用这种方式同时声明多个变量:

在这里插入图片描述
Rust中,每个变量必须被合理初始化之后才能被使用。使用未初始化变量这样的错误,在Rust中是不可能出现的(利用unsafe做hack除外)。

在这里插入图片描述
Rust里面的下划线是一个特殊的标识符,在编译器内部它是被特殊处理的。它跟其他标识符有许多重要区别。比如,以下代码就编译不过:
在这里插入图片描述

变量遮蔽

Rust允许在同一个代码块中声明同样名字的变量。如果这样做,后面声明的变量会将前面声明的变量“遮蔽”(Shadowing)起来。

在这里插入图片描述
从第5行开始,一直到这个代码块结束,我们没有任何办法再去访问前一个x变量,因为它的名字已经被遮蔽了。

变量遮蔽在某些情况下非常有用,比如,我们需要在同一个函数内部把一个变量转换为另一个类型的变量,但又不想给它们起不同的名字。

再比如,在同一个函数内部,需要修改一个变量绑定的可变性。

例如,我们对一个可变数组执行初始化,希望此时它是可读写的,但是初始化完成后,我们希望它是只读的。

在这里插入图片描述
反过来,如果一个变量是不可变的,我们也可以通过变量遮蔽创建一个新的、可变的同名变量。
在这里插入图片描述

类型推导

Rust的类型推导功能是比较强大的。它不仅可以从变量声明的当前语句中获取信息进行推导,而且还能通过上下文信息进行推导。

在这里插入图片描述
我们甚至还可以只写一部分类型,剩下的部分让编译器去推导,比如下面的这个程序,我们只知道players变量是Vec动态数组类型,但是里面包含什么元素类型并不清楚,可以在尖括号中用下划线来代替:

在这里插入图片描述
自动类型推导和“动态类型系统”是两码事。

Rust依然是静态类型的。

一个变量的类型必须在编译阶段确定,且无法更改,只是某些时候不需要在源码中显式写出来而已。

这只是编译器给我们提供的一个辅助工具。
Rust只允许“局部变量/全局变量”实现类型推导,而函数签名等场景下是不允许的,这是故意这样设计的。

这是因为局部变量只有局部的影响,全局变量必须当场初始化而函数签名具有全局性影响。

函数签名如果使用自动类型推导,可能导致某个调用的地方使用方式发生变化,它的参数、返回值类型就发生了变化,进而导致远处另一个地方的编译错误,这是设计者不希望看到的情况。

类型别名

我们可以用type关键字给同一个类型起个别名(type alias)。示例如下:
在这里插入图片描述
类型别名还可以用在泛型场景,比如:
在这里插入图片描述
type Double=(T,Vec);//小括号包围的是一个tuple,请参见后文中的复合数据类型那么以后使用Double的时候,就等同于(i32,Vec),可以简化代码。

静态变量

Rust中可以用static关键字声明静态变量。如下所示:

static GLOBAL:i32 =0;

与let语句一样,static语句同样也是一个模式匹配。与let语句不同的是,用static声明的变量的生命周期是整个程序,从启动到退出。

static变量的生命周期永远是’static,它占用的内存空间也不会在执行过程中回收。这也是Rust中唯一的声明全局变量的方法。

由于Rust非常注重内存安全,因此全局变量的使用有许多限制。这些限制都是为了防止程序员写出不安全的代码:

  • 全局变量必须在声明的时候马上初始化;
  • 全局变量的初始化必须是编译期可确定的常量,不能包括执行期才能确定的表达式、语句和函数调用;
  • 带有mut修饰的全局变量,在使用的时候必须使用unsafe关键字。
    在这里插入图片描述
    Rust不允许用户在main函数之前或者之后执行自己的代码。所以,比较复杂的static变量的初始化一般需要使用lazy方式,在第一次使用的时候初始化。在Rust中,如果用户需要使用比较复杂的全局变量初始化,推荐使用lazy_static库。

常量

在Rust中还可以用const关键字做声明。如下所示:

const GLOBAL: i32 =0;

编译器并不一定会给const常量分配内存空间,在编译过程中,它很可能会被内联优化。

因此,用户千万不要用hack的方式,通过unsafe代码去修改常量的值,这么做是没有意义的。

以const声明一个常量,也不具备类似let语句的模式匹配功能。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 实战 -- 创建 uni-admin 项目,部署到 uniCloud 前端网页托管(免费云空间)

创建 uni-admin 项目 可见 只能创建一个超级管理员,创建过后,登录页将不再显示 注册管理员账号 部署到 uniCloud 前端网页托管 部署成功,访问地址可预览效果! https://static-mp-7b65169e-151f-4fbb-a5ba-2125d4f56e3f.next.bs…

ES的索引库操作

索引库操作 索引库就类似数据库表,mapping映射就类似表的结构。 我们要向es中存储数据,必须先创建“库”和“表”。 1.mapping映射属性 mapping是对索引库中文档的约束,常见的mapping属性包括: type:字段数据类型&a…

面试宝典之JVM优化

J01、类加载的几个过程? 加载、验证、准备、解析、初始化。然后是使用和卸载了 J02、Minor GC 与 Full GC 分别在什么时候发生? 新生代内存不够用时候发生 MGC 也叫 YGC,JVM 内存不够的时候发生 FGC J03、java 中垃圾收集的方法有哪些? …

navicat for oracle

前言 Oracle中的概念并不是创建数据库,而是创建一个表空间,然后再创建一个用户,设置该用户的默认表空间为我们新创建的表空间,这些操作之后,便和你之前用过的mysql数据库创建完数据库一模一样了。 创建数据库 使用O…

C++20结构化绑定应用实例(二百五十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

微信订阅号 服务号区别

服务号和订阅号有什么区别?服务号转为订阅号有哪些作用?很多小伙伴想把服务号改为订阅号,但是不知道改了之后具体有什么作用,今天跟大家具体讲解一下。首先我们知道服务号一个月只能发四次文章,但是订阅号每天都可以发…

瑞吉外卖笔记系列(2) —— 完善员工的后台系统登录功能,实现员工信息管理

本文档主要 完善员工的后台系统登录功能,新增员工,员工信息分页查询,启用/禁用员工账号,编辑员工信息 一、完善后台系统登录功能 1.1 问题分析 目前存在的问题是:理论上,用户必须在 http://localhost:808…

宽度优先搜索算法(BFS)详解(超级详细讲解,附有大图)

目录 一.宽度优先搜索(BFS)是什么? 二.图解宽搜(BFS) 三.对比与发现 四。工具——队列 五.模板 六.最后 一.宽度优先搜索(BFS)是什么? 百度百科这样说: 宽度优先搜索…

蓝桥杯省赛无忧 STL 课件15 queue

01 queue队列 02 priority_queue优先队列 接下来介绍几种优先队列修改比较函数的方法 03 deque双端队列 04 例题讲解 https://www.lanqiao.cn/problems/1113/learning/?page1&first_category_id1&problem_id1113输入 5 IN xiaoming N IN Adel V IN laozhao N OUT …

抓交通肇事犯(python)

问题描述: 一辆卡车违反交通规则,撞人后逃跑。现场有三人目击该事件,但都没有记住车号,只记下了车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但…

【金融数据分析】计算2023年沪深300行业涨跌幅

本文我们来计算2023年沪深300行业涨跌幅&#xff0c;最后呈现的页面是这样的 先来说后端的代码&#xff0c;计算行业涨跌幅的原理就是将某个行业所有成分股的涨跌幅加起来&#xff0c;然后除以股票数量得到一个平均涨跌幅 // 查询行业涨跌幅public List<CSI300IndustryRankV…

如何将.NET 8.0的ASP.NET Core Web API部署成Windows服务

写在前面 前面写了一篇关于将.NET应用转换成Windows服务的方法&#xff0c;其实真正的目的是为了探索如何将Asp.Net Core Web Api 部署成Windows 服务。基于上一篇的基础&#xff0c;只需把创建 WebApplication 的代码放到 BackgroundService 的ExecuteAsync方法中即可。 其中…

【一】通信协议概述

通信协议概述 简介&#xff1a; 很早之前就思考了要写一下电力系统常用的几种通信协议&#xff0c;一直拖着也没有行动&#xff0c;这次终于下定决心来出一个《通信协议》这样的专栏。电力行业数字化方面资料较少&#xff0c;我理解主要一方面是数字化程度还不高&#xff0c;一…

笔记系统的部署架构

前天给笔记系统打了0.0.3的tag&#xff0c;一个简单的全栈功能闭环基本完成。既然是开源&#xff0c;因此&#xff0c;这里有必要分享一下部署结构&#xff0c;希望能够获得小伙伴们的反馈。 目前整个系统采用docker容器来部署。应用介绍 auth_app: 登录/注册的前端应用 web_ap…

WebRTC入门:基础的核心协议与概念(二十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

Open3D对产生偏差的点云数据进行校正

由于相机安装问题&#xff0c;导致点云数据两边翘起来&#xff0c;为了计算把翘起来的部分拉平整 import time import open3d as o3d; import numpy as np; import matplotlib.pyplot as plt from scipy.signal import find_peaks import pandas as pdOriginalPly o3d.io.rea…

自养号测评:掌握Shopee运营黑科技的必备攻略

虾皮卖家们经常挂在嘴边的“权重”&#xff0c;简而言之&#xff0c;就是商品或店铺在Shopee平台上受到重视的程度。它的存在是为了评估商品或店铺是否满足用户需求&#xff0c;能否助力订单转化&#xff0c;为平台创造更多收益。就像我们给孩子们打分一样&#xff0c;分数越高…

Vue3函数式弹窗实现

要在一些敏感操作进行前要求输入账号和密码&#xff0c;然后将输入的账号和密码加到接口请求的header里面。如果每个页面都去手动导入弹窗组件&#xff0c;在点击按钮后弹出弹窗。再拿到弹窗返回的账号密码后去请求接口也太累了&#xff0c;那么有没有更简单的实现方式呢&#…

python_locust压测

可以在命令行启动&#xff0c;cmd命令框&#xff0c;进入此文件的目录输入&#xff1a; locust -f .\dash.py --host"https://litemall.hogwarts.ceshiren.com" -f&#xff1a; 指定性能测试脚本文件的绝对路径。 –host&#xff1a; 指定被测试应用的URL的地址&…

Qt/QML编程学习之心得:Grid、GridLayout、GridView、Repeater(33)

GRID网格用处非常大,不仅在excel中,在GUI中,也是非常重要的一种控件。 Grid 网格是一种以网格形式定位其子项的类型。网格创建一个足够大的单元格网格,以容纳其所有子项,并将这些项从左到右、从上到下放置在单元格中。每个项目都位于其单元格的左上角,位置为(0,0)。…