0x01 了解变量
Rust语言的变量是一种绑定语义,相当于是把一个变量名和一个值绑定在一起,从而建立起了关联关系,类似于键值对。为了安全性的考虑,Rust的变量默认是不可以改变的,当然Rust也提供了另一种变量——可变变量。
0x02 命名规范
Rust变量名可以由字母,数字或者下划线组成。同时还有以下3个限制条件:
- 不能以数字开头
- 字母区分大小写
- 不能只有下划线
0x03 变量绑定
在其它语言中,我们用 var a = "hello world" 的方式给 a 赋值,也就是把等式右边的 "hello world" 字符串赋值给变量 a ,而在 Rust 中,我们这样写: let a = "hello world" ,同时给这个过程起了另一个名字:变量绑定。
//不可变变量
let a = 10;
//可变变量
let b = 10;
//使用下划线开头忽略未使用的变量
let _c = 20;
0x04 变量解构
let 表达式不仅仅用于变量的绑定,还能进行复杂变量的解构:从一个相对复杂的变量中,匹配出该变量的一部分内容:
let (a, mut b): (bool,bool) = (true, false);
0x04 变量和常量之间的差异
- 常量不允许使用
mut。常量不仅仅默认不可变,而且自始至终不可变,因为常量在编译完成后,已经确定它的值。 - 常量使用
const关键字而不是let关键字来声明,并且值的类型必须标注。 - 静态常量使用
static关键字。
静态变量和常量很相似,但是在一个程序中,静态变量拥有精确固定的内存地址,对于静态变量的所有引用都指向相同的内存地址。静态变量也存在生命周期,但是其生命周期在程序中是最长的。静态变量不会在程序结束时调用
drop函数。
静态变量是可以用mut来修饰的,一旦静态变量可变,就会出现多线程同时访问的场景,从而引发内存不安全的问题,因此对于static mut声明的变量必须在unsafe块中进行定义(有关unsafe的内容将在后续章节介绍)。
0x05 变量遮蔽 (Shadowing)
Rust 允许声明相同的变量名,在后面声明的变量会遮蔽掉前面声明的,如下所示:
fn main() {
let x = 5;
// 在main函数的作用域内对之前的x进行遮蔽
let x = x + 1;
{
// 在当前的花括号作用域内,对之前的x进行遮蔽
let x = x * 2;
println!("The value of x in the inner scope is: {}", x);
}
println!("The value of x is: {}", x);
}
这个程序首先将数值 5 绑定到 x,然后通过重复使用 let x = 来遮蔽之前的 x,并取原来的值加上 1,所以 x 的值变成了 6。第三个 let 语句同样遮蔽前面的 x,取之前的值并乘上 2,得到的 x 最终值为 12。当运行此程序,将输出以下内容:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
...
The value of x in the inner scope is: 12
The value of x is: 6
fn main() {
//练习1
//error write
//Rust的变量默认情况下是不可变的。
// let x = 5;
// println!("The value of x is {}", x);
// // x = 6;
// println!("The value of x is {}", x);
// println!("Hello, world!");
//练习2
//在变量前加一个mut,则此变量为可变变量
// let mut x = 5;
// println!("The value of x is : {}",x);
// x = 6;
// println!("The value of x is : {}",x);
//练习3
//创建一个变量但是不使用,Rust会给一个警告
//以下划线作为变量的开头,Rust则不会给一个警告
// let _x = 5;
// let y = 10;
//练习4
//let表达式可以进行复杂变量的解构,从一个相对复杂的变量中
//匹配出该变量的一部分内容
// let (a,mut b) : (bool,bool) = (true,false);
// println!("a = {:?},b = {:?}",a,b);
// b = true;
// assert_eq!(a,b);
//练习5
//赋值语句中使用元祖,切片,结构体
// let (a,b,c,d,e);
// (a,b) = (1,2);
// // _ 代表匹配一个值,但是不关系具体的值是什么,因此没有使用
// //一个变量名而是使用了 _
// [c,..,d,_] = [1,2,3,4,5];
// Struct{e,..} = Struct{e:5};
// assert_eq!([1,2,1,4,5],[a,b,c,d,e]);
//练习6
/*
常量不允许用mut。常量不仅仅默认不可变,而且自始至终不可变,因为常量
编译完成后,已经确定它的值
常量使用const关键字而不是let关键字来申明
*/
// const MAX_POINTS:u32 = 100;
//练习7
//变量遮蔽
//Rust允许申明相同的变量名,后面申明的变量会遮蔽掉前面的申明
let x = 5;
//对let x = 5;变量申明进行遮蔽
let x = x + 1;
println!("The value of x is : {}",x);
{
//在当前作用域内{},对之前的x进行遮蔽
let x = x + 2;
println!("The value of x is : {}",x);
}
println!("The value of x is : {}",x);
//字符串类型
let spaces = " ";
println!("The value of spaces is : {}",spaces);
//usize数值类型
let spaces = spaces.len();
println!("The value of spaces is : {}",spaces);
}
// struct Struct{
// e:i32
// }