05-变量与可变性

前言

前几篇文章中,我们已经对 Rust 有了一个初步的了解,并通过一个 猜数游戏 的小程序的开发,抢先接触了 Rust 的一些语法特性,但大多都是浅尝辄止,未曾深入,从这个章节开始,我们就来一步步地深入学习这些语法特性,力求将这些语法特性都吃透,并能够灵活应用。

接触程序,我们首先需要接触变量,所以,我们今天这篇文章就以变量与可变性 作为切入点正式进入 Rust 的语法世界。

let

我们在前几章已经反复讲了好多次 let 相关的内容了,这边就不再赘述了,总得来说就是:

使用 let 可以定一个不可变的变量,如果想要这个变量可变,需要在 let 后加一个 mut 关键字注明,否则会报错。变量定义后,可以再次用 let 对同名变量进行重新定义(Shadowing),常用与变量的类型转换

具体的使用示例,可以查看本专题的前几个章节,这边就不再赘述了。

需要特别注意的是,let 变量是不能再全局作用域中定义的,通常我们都是在:函数作用域代码块作用域循环作用域 内部使用。如果在全局作用域上使用 let,你将会看到 Rust 抛出的报错:

这也是 Rustletts/js 的中的 let 很大的不同点,在 ts/js 当中,我们可以毫无顾忌的在全局作用域上使用 let 关键字定义些变量并在全局范围内可以随意调用和修改。而到了 Rust ,我们就要改变我们这个使用习惯了,不然得到的只会是 Rust 的无情报错。

变量与常量

typescript当中,可以使用使用 let定义变量,用于存储一些可变的值,同时也可以使用 const 定义常量,用于定义一些永远不变的值。而在 Rust 也是一样的,我们同样可以使用 const 关键字用来定义一些恒定不变的值,即常量。

有同学可能会有疑问,在 Rust 当中,let 在没有声明 mut 的时候,也是不可变的,那不是跟 const 的作用一样了吗?多一个 const 有什么用呢?

  • 不可使用 mut :常量永远都是不可变的,不可以使用 mut 关键字。

  • 使用 const 关键字 :在 Rust 当中,声明常量跟在 typescript 当中声明常量的关键字是一样的,都是 const

  • 类型必须显示标注 :与 typescript 中常量可以根据初始赋值时变量的类型自动推论不同,在 Rust 当中,常量的类型必须显式声明,否则会报错

  • 可在全局作用域中声明 :与 let 不同的是,const 关键字与 ts/js 一样,都可以在全局作用域范围内生命。

  • 常量只能绑定常量表达式:常量只能绑定常量表达式,无法绑定到函数的调用结果,或者是只能在运行时产生的值。

  • 在作用域内持续有效:在程序运行期间,常量在其声明的作用域内是始终有效的。

  • 命名规范 : 在 Rust 当中,常量的命名规范是全大写,多个单词之间使用 _ 分隔,如:FIRST_NAME

    上面的代码其他的应该都很容易理解,有一点比较让人费解的就是 后面的赋值与中的 10_000,或许有些同学不清楚什么意思,这其实是我们在定一个数字的时候,可以用 _ 对数字进行格式化,增加数字的可读性,其实上面的 10_000 就是代表 10000 这个数字。其实这个特性目前也已经被 js 支持了,我们在最新的 chrom 浏览器的控制台,直接使用这种方式定义数值也是能够正常使用的:

变量的隐藏(shadowing)

前端开发的同学应该都很清楚,以下这两种方式,在 JS/TS 中是不允许的:

typescript 复制代码
let num = 10;
// ❌ 不能重复得使用 let 进行同名变量的定义
let num = 20;

const name = "kiner";
// ❌ 不能重复得使用 const 进行同名常量的定义
const name = 18;

然而,在 Rust 当中,将会颠覆你之前的使用习惯:

rust 复制代码
let num: i32 = 10;
// ✅ 这样是合法的,不会报错的,我们在这行之后,num 的类型是 u32,而在这之前,类型则是 i32
let num: u32 = 100;

const NAME: $str = "kiner";
// ✅ 这样是合法的,不会报错的,我们在这行之后,NAME 的类型是 u32,而在这之前,类型则是 &str
const NAME: u32 = 10;

Rust 当中,我们把这种能够重新定义同名变量的特性称之为:Shadowing(隐藏) ,即:变量隐藏。我们在上几篇文章当中,也有初步的接触到变量隐藏的概念,当时是为了实现一个猜数游戏,利用变量隐藏的特性,实现类将字符串类型的用户输入转换成整型的任务。

rust 复制代码
let mut guess = String::new();
    
io::stdin().read_line(&mut guess).expect("读取行失败");

println!("你猜测的数是:{}", guess);

// 类型转换,将原本用户输入的字符串转换成之后方便比较的整型
let guess: i64 = match guess.trim().parse() {
  // 如果转换成功,则将其值赋值给 guess
  Ok(num) => num,
  // 如果转换失败,则使用 continue 关键字跳过本次循环,继续下一次循环,让用户重新输入
  Err(_) => {
    println!("请输入一个数字!");
    continue;
  },
};

总结一下,就是我们可以用后面的 let 关键字定义的同名变量隐藏到前面的同名变量,并且声明的新变量的类型可以跟之前的类型是不一样,如之前是整型,你可以重新声明成字符串类型。

结语

至此,我们已经详细的了解了在 Rust 当中定义变量和常量的方式,也了解了变量的可变性以及 Rust 与其他语言很大的一个不同点:变量隐藏(Shadowing)的概念、使用场景等等,相信大家都已经对变量的相关知识已经更加清晰了吧。

相关推荐
weixin_518285052 小时前
深度学习笔记11-神经网络
笔记·深度学习·神经网络
龙鸣丿5 小时前
Linux基础学习笔记
linux·笔记·学习
Nu11PointerException7 小时前
JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习
笔记·学习
亦枫Leonlew9 小时前
三维测量与建模笔记 - 3.3 张正友标定法
笔记·相机标定·三维重建·张正友标定法
考试宝9 小时前
国家宠物美容师职业技能等级评价(高级)理论考试题
经验分享·笔记·职场和发展·学习方法·业界资讯·宠物
黑叶白树11 小时前
简单的签到程序 python笔记
笔记·python
幸运超级加倍~11 小时前
软件设计师-上午题-15 计算机网络(5分)
笔记·计算机网络
老猿讲编程12 小时前
用示例来看C2Rust工具的使用和功能介绍
rust
金庆12 小时前
How to set_default() using config-rs crate
rust·config·set_default·valuekind
芊寻(嵌入式)13 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习