Rust编程基础之变量与可变性

2023-10-30 04:44

本文主要是介绍Rust编程基础之变量与可变性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.Rust变量

在Rust语言中, 变量默认是不可改变的(immutable), 这是Rust提供给我们的众多优势之一, 让我们可以充分利用Rust提供的安全性和简单并发性来编写代码。

当变量不可变时, 一旦值被绑定在一个名称上, 就不能改变这个值。下面是一段代码的例子:

fn main() {let x = 1;println!("The value of x is: {x}");x = 2;println!("The value of x is: {x}");
}

这段代码如果是其它高级语言, 看不出有什么问题, 定义了一个变量,先赋值1,然后打印输出, 再将该值赋值2, 再打印该值的内容。

但如果你使用的是支持Rust开发语言的IDE, 在这段代码中会给出一个错误标识, 将鼠标移到上面,会看到一段错误提示,如图:

错误含义就是不可多次为一个不可变的变量赋新值。

如果我们使用Rust自带的编译器进行编译, Rust会很贴心的告诉我们错误在哪个位置, 错误的原因, 错误怎么纠正,如图:

在上图的提示中, Rust编译器建议我们想改变变量的值, 应该在let后面加上mut关键字, 这样变量就可以被改变了。

修改代码如下:

fn main() {let mut x = 1;println!("The value of x is: {x}");x = 2;println!("The value of x is: {x}");
}

再次编译, 可以看到已经正确打印了变量内容,如图:

2.Rust常量

类似于不可变变量, 常量(constants)是绑定到一个名称的不允许改变的值, 不过常量和变量还是有一定的区别。

首先, 不允许对常量使用mut, 常量不仅默认不可变, 而且总是不可变。声明常量使用const关键字而不是let, 并且必须注明值的类型。

常量可以在任何作用域中声明,包括全局作用域, 这在一个值需要被很多部分的代码用到时很有用。

最后一个区别是,常量只能被设置为常量表达式,而不可以是其它任何只能在运行时计算出的值。

以下是一个常量的声明例子:

const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 *3;

常量的名称是 THREE_HOURS_IN_SECONDS,它的值被设置为 60(一分钟内的秒数)乘以 60(一小时内的分钟数)再乘以 3(我们在这个程序中要计算的小时数)的结果。Rust 对常量的命名约定是在单词之间使用全大写加下划线。编译器能够在编译时计算一组有限的操作,这使我们可以选择以更容易理解和验证的方式写出此值,而不是将此常量设置为值 10,800。

在声明它的作用域之中,常量在整个程序生命周期中都有效,此属性使得常量可以作为多处代码使用的全局范围的值,例如一个游戏中所有玩家可以获取的最高分或者光速。

将遍布于应用程序中的硬编码值声明为常量,能帮助后来的代码维护人员了解值的意图。如果将来需要修改硬编码值,也只需修改汇聚于一处的硬编码值。

3.隐藏

在Rust中,我们可以定义一个与之前变量同名的新变量, 在这种情况下, 称之为第一个变量被第二个隐藏(Shadowing)了, 这意味着当我们使用变量的名称时, 编译器将看到第二个变量。实际上,第二个变量“遮蔽”了第一个变量,此时任何使用该变量名的行为中都会视为是在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。可以用相同变量名称来隐藏一个变量,以及重复使用let关键字来多次隐藏。

看一段下面的代码:

fn main() {let x = 5;let x = x + 1;{// 进入隐藏作用域let x = x * 2;println!("The value of x in the inner scope is: {x}");}println!("The value of x is: {x}");
}

我们先在代码下个断点, 通过调试状态观察变量值的情况,如图:

从上图中可以看到, 进入花括号作用域后, x 经过计算已经变成了12, 所以第一个打印的应该是12。

如果出了作用域会怎样呢, 继续单步走一下退出作用域,如图:

可以看到, 出了作用域之后, X的值又变成了6, 因此第二个打印语句的结果就是6。

因此最终输出如下:

隐藏与将变量标记为 mut 是有区别的。当不小心尝试对变量重新赋值时,如果没有使用 let 关键字,就会导致编译时错误。通过使用 let,我们可以用这个值进行一些计算,不过计算完之后变量仍然是不可变的。

mut 与隐藏的另一个区别是,当再次使用 let 时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字。例如,假设程序请求用户输入空格字符来说明希望在文本之间显示多少个空格,接下来我们想将输入存储成数字(多少个空格):

let spaces = "   ";
let spaces = spaces.len();

第一个 spaces 变量是字符串类型,第二个 spaces 变量是数字类型。隐藏使我们不必使用不同的名字,如 spaces_strspaces_num;相反,我们可以复用 spaces 这个更简单的名字。然而,如果尝试使用 mut,将会得到一个编译时错误,如下所示:

let mut spaces = "   ";
spaces = spaces.len();

错误提示如下:

4.总结

在本篇文章中, 我们学到以下知识点:

1.Rust变量定义及可变性、不可变性的灵活应用。

2.Rust常量的基本作用域和命名规则。

3.Rust变量的隐藏属性规则、原理和应用。

在下一篇文章中,我们将学习Rust更多的数据类型。包括:整型、浮点型、布尔型、字符类型、元组、数组。

这篇关于Rust编程基础之变量与可变性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/305659

相关文章

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

mysql的基础语句和外键查询及其语句详解(推荐)

《mysql的基础语句和外键查询及其语句详解(推荐)》:本文主要介绍mysql的基础语句和外键查询及其语句详解(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录一、mysql 基础语句1. 数据库操作 创建数据库2. 表操作 创建表3. CRUD 操作二、外键

Python基础语法中defaultdict的使用小结

《Python基础语法中defaultdict的使用小结》Python的defaultdict是collections模块中提供的一种特殊的字典类型,它与普通的字典(dict)有着相似的功能,本文主要... 目录示例1示例2python的defaultdict是collections模块中提供的一种特殊的字

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

C#基础之委托详解(Delegate)

《C#基础之委托详解(Delegate)》:本文主要介绍C#基础之委托(Delegate),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 委托定义2. 委托实例化3. 多播委托(Multicast Delegates)4. 委托的用途事件处理回调函数LINQ

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制