环境
- windows 10 64bit
变量
Rust 中的变量默认是不可变的,这点跟目前市面上主流编程语言中的变量是不同的。不过,可以通过在变量名前面添加关键字 mut,来让变量可变。
let total = 100;
total = 200;

可以看到提示 cannot assign twice to immutable variable,意思就是不可变变量无法被赋值2次,这时候,我们在变量名前面加上 mut 就不会有问题了,total 变量可以被重新多次赋值。
let mut total = 100;
total = 200;
这里需要注意一点,常量不能够使用 mut 关键字,而且声明常量用的是 const 关键字,最后还必须显式的指明数据的类型,如
// 无符号32位数
const MAX_NUMBER: u32 = 100;
Rust 还有个重要的特性,就是隐藏 shadow,一个新声明的变量可以覆盖掉原来的同名变量
let total = 100;
let total = total + 1;
代码中的第二个 total 会隐藏掉第一个 total,后面使用的 total 变量都指的是第二个 total 变量
数据类型
在 Rust 中,每一个值都有其对应的数据类型,这里将数据类型分为两大类,标量类型(scalar) 和复合类型(compound)。标量类型包括了整数类型、浮点数类型、布尔类型、字符类型;而复合类型包含了元祖(tuple)和数组(array)。
整数类型
分为有符号数(以字母 i 开头)和无符号数(以字母 u 开头)

对于一个位数为 n 的有符号整数类型,它可以存储从负的2的 n-1 次方到2的 n-1 次方减1范围内的所有整数。比如对于 i8 来讲,它可以存储从-128到127之间的所有整数。而对于无符号整数类型而言,则可以存储从0到2的 n 次方减1范围内的所有整数。以 u8 为例,它可以存从0到255之间的所有整数。
注意到上表中,还有 isize 和 usize 两种特殊的整数类型,它们的长度取决于程序运行的目标平台。在64位架构上,它们就是64位的,而在32位架构上,它们就是32位的。
let total:i8 = 200;
给变量赋值超过了它的范围,编译器就会报错

浮点数类型
浮点数就是带小数的数字,占用32位的 f32 和占用64位的 f64,默认情况下,使用的是 f64
let x = 100.0;
let y: f32 = 100.0;
布尔类型
Rust 中的布尔类型占据单个字节空间,它只有2个可能的值,一个是 true,另一个是 false,类型名称是 bool
let isFlag: bool = true;
let isFlag = false;
字符类型
Rust 中,用 char 来表示字符类型,是单个字符,用单引号表示,而字符串用双引号表示
let c: char = 'A';
元组类型
将多个不同类型的值组合起来就是元组,元组在声明后无法增加或减少其中的元素数量。
let tup: (char, u32, f64) = ('a', 100, 49.9);
// 通过.操作符来访问元组中的元素,元组的索引从0开始
println!("{}", tup.0);
数组类型
除了元组类型,数组类型同样可以将多种数据类型组合在一起,不过,与元组不同的是,数组要求每一个元素都必须是相同的类型,而且数组一旦声明后,就不能随意更改大小。
let arr = [4, 3, 2, 1];
// 通过索引来访问数组中的元素,索引从0开始
println!("{}", arr[0]);
函数
前面已经接触过了函数,那就是 main 函数,它是程序的入口。
fn main() {
println!("Hello, world!");
}
其中,fn 是关键字,表明这是一个函数,main 是函数名, 大括号 {} 内的内容是函数体,它是函数逻辑实现的地方。main 函数中并没有参数,来看下面这个例子。
fn add(x: i32, y: i32) {
println!("x={}", x);
println!("y={}", y);
}
这里的小括号中有2个参数,2个参数都是 i32 数据类型。
在 Rust 中,有2个容易混淆的概念,语句(statement)和表达式(expression)。语句指那些执行操作但不返回值的指令,而表达式则是指会进行计算并产生一个值作为结果的指令。
比如,使用 let 声明一个变量就是一条语句
let total: u32 = 100;
表达式就更常见了,如上面的字面量100、数值计算、函数调用、println! 宏调用等都是表达式
接着,看一下函数的返回值,在函数参数后面加上 --> 返回值类型
fn add(x: i32, y: i32) -> i32 {
println!("x={}", x);
println!("y={}", y);
}
最后看一个完整的例子
fn add(x: i32, y: i32) -> i32 {
println!("x={}", x);
println!("y={}", y);
return x + y;
}
fn main() {
println!("Hello, world!");
// 函数调用是表达式,将表达式的值赋给num变量
let num = add(5, 4);
// main函数的返回值是隐藏了,其实就是最后一个表达式的值,本例中是宏调用
println!("number={}", num);
}

控制流
Rust 中通过 if 和 else 将逻辑进行分流,这和绝大多数编程语言是一样的
let num = 99;
if(num > 100) {
println!("big than 100.\n")
} else {
println!("small than 100.\n")
}
需要注意的是,这里的条件表达式期待的是一个 bool 类型,而 Rust 不会自动尝试将非布尔类型的值转换为布尔类型,我们必须显式地在 if 表达式中提供一个布尔类型作为条件,这一点与某些编程语言是不一样的。
通过 else if 语句,可以实现多重的条件判断
let num = 100;
if(num > 100) {
println!("big than 100.\n")
} else if(num == 100) {
println!("equal to 100.\n")
} else {
println!("small than 100.\n")
}
除了条件语句,Rust 为我们提供了3种循环,分别是 loop、while 和 for。
在需要循环执行的代码块前面加上 loop 关键字,就能让代码块无限循环的执行下去
loop {
println!("Hello Rust.");
}
要想退出循环,可以使用 break 关键字
let mut counter = 0;
loop {
println!("Hell Rust.");
counter = counter + 1;
if(counter > 20) {
break;
}
}
while 循环是在每次执行循环体之前都去判断一次条件,如果条件为真则执行代码片段。这种模式可以通过 loop、if、else 及 break 关键字的组合使用来实现。
let mut counter = 100;
while (counter > 0) {
println!("counter={}", counter);
counter = counter - 1;
}
for 循环也是使用频率非常的一种,它通常被用来遍历集合中的元素。
let scores = [90, 93, 95, 97, 99, 100];
for score in scores {
println!("score={}", score);
}
注释
在 Rust 中,使用 // 来表名注释,写在语句或者表达式的前面,多行注释使用 /**/。
let score = 100;
// let sc = 0;
/*
let a = 1;
let b = 2;
let c = 3;
*/
为了让自己的代码更加的通俗易懂,建议大家多写注释。编译器在编译的过程中会忽略掉注释,注释不会影响到程序的性能。