3.1.0. 写在正文之前
欢迎来到Rust自学的第三章,一共有6个小节,分别是:
- 变量与可变性(本文)
- 数据类型:标量类型
- 数据类型:复合类型
- 函数和注释
- 控制流:
if else
- 控制流:循环
通过第二章的小游戏(没看的初学者强烈建议看一下),相信你已经学会了基本的Rust语法,而在第三章我们将更深一层,了解Rust中的通用的编程概念。
喜欢的话记得点赞、收藏加关注哦,想要跟着学习可以关注专栏哦
3.1.1. 可变/不可变变量的声明
-
声明变量使用
let
关键字 -
默认情况下,变量是不可变的。以下是错误例,报错内容在注释里:
fn main(){
let machine = 6657;
machine = 0721; //Error: cannot assign twice to immutable varible
println!("machine is {}", machine);
}
- 在
let
后加上mut
才能声明可变变量。以下是成功例,输出内容在注释里:
fn main(){
let mut machine = 6657;
machine = 721;
println!("machine is {}", machine);//Output: machine is 721
}
3.1.2 变量与常量
有很多人在刚开始学Rust的时候都会搞不清不可变变量与常量(constant
)的区别在哪里。常量在绑定值后也是不可变的,但它与不可变变量的区别很大:
- 常量不能使用
mut
,一旦声明就不可变。 - 声明常量需要使用
const
关键字,它的类型必须被显示标注;不可变变量可以不显示标准。 - 常量可以在任何作用域内声明,包括全局作用域。
- 常量只能绑定到常量表达式,无法绑定到函数的调用结果或只能在运行时才能计算出的值
- 在程序运行期间,常量在其声明的作用域中一直有效。
- 命名规范:Rust里常量使用全大写字母,每个单词之间用下划线分开,例如:
MAX_POINTS
常量声明的例子:
const WJQ: i32 = 66570721;
fn main(){
const WJQ_MACHINE:u32 = 6_657;
let mut machine = 6657;
machine = 721;
println!("machine is {}", machine);//Output: machine is 721
println!("WJQ is {}", WJQ);//Output: WJQ is 66570721
println!("WJQ_MACHINE is {}", WJQ_MACHINE);//Output: WJQ_MACHINE is 6657
}
其中的i32
、u32
是其类型。Rust支持插入下划线增强可读性,这个例子中的6_657
写成6657
也是可以的。这个常量既可以在全局,也可以声明在main
函数里,也可以在其他作用域中。
3.1.3 隐藏(Shadowing)
在之前的小游戏程序中声明变量时就提过一嘴,Rust允许使用同名新变量来隐藏原来同名的新变量,学名叫做类型遮蔽(当一个变量、函数或类型的名称在当前作用域中被重新定义时,隐藏了外部作用域中同名的变量、函数或类型),每次遮蔽时,原变量的值和类型都会被新变量替代。它允许代码复用这个变量名而无需声明新的变量。
这里可以举一个例子:
fn main(){
let a = 1;
println!("{}",a);
let a = "one";
println!("{}",a);
}
这么做程序不会报错,并且打印出了:
1
one
当程序执行到第二行时,a被赋值为1,所以打印出的是1;在第四行,程序注意到a被复用了,就会抛弃原来的值1,把a赋值为"one",所以下一行打印的就是one。这就是类型遮蔽。
要注意的是,使用类型遮蔽和把变量声明为可变变量是由不同之处的:
- 在类型遮蔽中,使用
let
声明的新变量依然是不可变变量 - 在类型遮蔽中,使用
let
声明的同名新变量的类型可以与之前不同
fn main(){
let machine = "wjq";
let machine = 6657;
println!("{}",machine);
}
上边这个程序使用了类型遮蔽,不会报错。第二次 let machine = 6657;
是新声明的变量,与之前的 machine
并没有关系。
fn main(){
let mut machine = "wjq";
machine = 6657;
println!("{}",machine);//Error: expected `&str`, found integer
}
上边这个程序使用了可变变量,Rust 是强类型语言,变量的类型在首次声明时确定,赋值 machine = 6657
试图将一个整数赋值给一个字符串类型变量,类型不匹配,导致编译错误:expected &str
, found integer