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语句的模式匹配功能。

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

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

相关文章

Linux系统编程(十一):高级 IO

参考引用 UNIX 环境高级编程 (第3版)嵌入式Linux C应用编程-正点原子 1. 非阻塞 I/O 阻塞就是进入了休眠状态,交出了 CPU 控制权阻塞 I/O 就是对文件的 I/O 操作(读写操作)是阻塞式的,非阻塞 I/O 就是对文件的 I/O 操作是非阻塞的…

网络技术基础入门全套实验-厦门微思网络CCNA实验手册

知识改变命运,技术就是要分享,有问题随时联系,免费答疑,欢迎联系! 微思简介(https://www.xmws.cn) 微思成立于2002年,是一个诚信敬业、积极向上、充满活力、专注技术服务的企业。 微思获得了八…

电子学会2023年12月青少年软件编程(图形化)等级考试试卷(四级)真题,含答案解析

青少年软件编程(图形化)等级考试试卷(四级) 分数:100 题数:24 一、单选题(共10题,共30分) 1. 运行下列程序,输入“abcdef”,程序结束后,变量“字符串”是?( )

Linux--部署 Tomcat 及其负载均衡

1.案例前置知识点 1)Tomcat简介 名称由来:Tomcat最初是由 Sun的软件构架师詹姆斯邓肯戴维森开发的。后来他帮助将其变 为开源项目,并由Sun贡献给Apache软件基金会。由于大部分开源项目OReilly都会出一本相关的 书,并且将其封面设…

SpringMVC视图

文章目录 1、ThymeleafView2、转发视图3、重定向视图4、视图控制器view-controller5、总结 SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户SpringMVC视图的种类很多,默认有转发视图和重定向视图当工程引入js…

2024几个测试接口的好工具,效率加倍~

作为一名后端程序员,一定要对自己写的接口负责,保证接口的正确和稳定性。因此,接口测试也是后端开发中的关键环节。 但我相信,很多朋友是懒得测试接口的,觉得这很麻烦。一般自己写的接口自己都不调用,而是…

在Linux上搭建Maven仓库

目录 一、下载安装包二、安装maven三、修改配置文件settings.xml四、配置环境变量五、测试maven是否可用 一、下载安装包 我在这里为大家准备好了apache-maven-3.5.0-bin.tar.gz,百度网盘下载链接如下: 链接:https://pan.baidu.com/s/1bGun…

NodeJs 第十一章 express

Express 是基于 Node.js 平台,快速、开放、极简的 web 开发框架 基本使用 安装 npm install express --save示例代码 const express require(express) const app express() const port 3000app.get(/, (req, res) > {res.send(Hello World!) })app.listen(…

NSR原理描述

相关概念 HA(High Availability):高可靠性/高实用性的简称,这里指主备板间的备份通道。NSF(Non-Stop Forwarding):不间断转发。NSR(Non-Stop Routing):不间断…

24年春招要来了,大学生第一次实习去大厂重要么?

春招要来了,大学生第一次实习去大厂重要么? 1.错峰实习。2.继任直招。3.优化简历,匹配优先。4. 善用新技术 先说一个暴论: 实习一定要去大厂,尤其是非头部院校的同学,你就算进去打螺丝,也要进大厂 关于我&#xff1a…

无需任何三方库,在 Next.js 项目在线预览 PDF 文件

前言: 之前在使用Vue和其它框架的时候,预览 PDF 都是使用的 PDFObject 这个库,步骤是:下载依赖,然后手动封装一个 PDF 预览组件,这个组件接收本地或在线的pdf地址,然后在页面中使用组件的车时候…

【python】08.面向对象编程基础

面向对象编程基础 活在当下的程序员应该都听过"面向对象编程"一词,也经常有人问能不能用一句话解释下什么是"面向对象编程",我们先来看看比较正式的说法。 "把一组数据结构和处理它们的方法组成对象(object&#…

Redis入门-redis的五大数据类型+三种特殊的数据类型

前言:Redis有五大基本类型与三种特殊类型的介绍 Redis有五大基本类型:字符串(string)、哈希(hash)、列表(list)、集合(set)和有序集合(sorted se…

大模型实战营Day4 XTuner大模型单卡低成本微调实战

FINETUNE简介 LLM下游应用中,增量预训练和指令跟随是经常会用到的两种微调模式 指令跟随微调 使用场景:让模型学会对话模板,根据人类指令进行对话 训练数据:高质量的对话,问答数据 为什么需要指令微调? 因为…

前端重置密码报错记录

昨天晚上,我写了重置密码的前端,测试的时候报错 今天上午,我继续试图解决这个问题,我仔细检查了一遍,前端没有问题 可以正常接收输入的数据并且提交 但是后端接收到的数据为空,后端接口也没有问题 但后端收…

大模型核心技术原理: Transformer架构详解

在大模型发展历程中,有两个比较重要点:第一,Transformer 架构。它是模型的底座,但 Transformer 不等于大模型,但大模型的架构可以基于 Transformer;第二,GPT。严格意义上讲,GPT 可能…

vscode无法自动补全

前提:安装c/c插件 c/c插件功能非常强大,几乎能满足日常编码过程中常用的功能;因为也包含自动补全的功能,开启方法如下: 文件->首选项->设置: 扩展->c/c->Intellisense,找到Intell…

C++多线程学习[三]:成员函数作为线程入口

一、成员函数作为线程入口 #include<iostream> #include<thread> #include<string>using namespace std;class Mythread { public:string str;void Test(){cout << str << endl;} }; int main() {Mythread test;test.str "Test";thr…

大数据-hive函数与mysql函数的辨析及练习-将多行聚合成一行

目录 1. &#x1f959;collect_list: 聚合-不去重 2. &#x1f959;collect_set(col): 聚合-去重 3. &#x1f959;mysql的聚合函数-group_concat 4. leetcode练习题 1. &#x1f959;collect_list: 聚合-不去重 将组内的元素收集成数组 不会去重 2. &#x1f959;collec…

mac 上 ssh: connect to host localhost port 22: Connection refused

1。 问题 在搭建hadoop环境的时候 发现ssh localhost 在报错 2. 解决 打开系统设置 -> 共享 -> -> 在左边服务中选择 远程登录 注意红框这些选项慎重选择&#xff01;&#xff01;&#xff01; 修改后&#xff0c;在终端再次 ssh localhost 发现登录成功了 如果…