1. 变量和可变性

Rust 定义一个变量默认是不可变的,这一点与其他编程语言不同。

1
2
let x = 10;
x = 11; // 这里会编译出错,

如果要定义可变量,需要使用 mut

1
2
let mut x = 10;
x = 11;

用 let 先定义一个变量,再次用 let 定义一个变量,会将之前的变量覆盖,虽然同名,但也不是原来的变量了,这叫做 Shadowing

1
2
let x = 10;
let x = "Hello";

常量的定义使用 const,常量是永远不会变的量,常量必须在定义的时候注明数据类型

1
const MAX_SCORE: i32 = 10000;

2. 标量数据类型

Rust 数据类型可以分为标量类型和复合类型,标量类型有四种 整型,浮点型,布尔型,字符型。而整型分为 8位、16位、32位、64位、128位,动态长度这几种,每一种又分为有符号型,无符号型。浮点数分为 32位、64位。

关键字:
整型有符号型: i8 i16 i32 i64 i128 isize
整型无符号型: u8 u16 u32 u64 u128 usize

整型默认类型为 i32。注意 isize usize 的长度是动态的,如果运行程序的计算机是32位的,则为32位,如果计算机为64位的,则为64位。另外,在Rust中遍历集合时,常用 isizeusize

浮点型: f32 f64 浮点型默认是 f64
布尔型: bool
字符型: char

字符型注意,在 Rust 中,char 类型是占4个字节的,这一点与其他编程语言不一样。char 类型,可以表示一个 unicode 字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 整型
let x = 1000;
let x = 1_000; // 对的,这样定义也可以
let x = 0xff; // 十六进制
let x = 0x_ff;
let x = 0o77; // 八进制
let x = 0o_77;
let x = 0b11110010; // 二进制
let x = 0b_11110010; // 这样定义也可以
let x = b'A'; // Byte (u8),如果打印的话,是打印出 A 对应的 Ascii 码
let x: i32 = 12; // 也可以加上数据类型
let x: u32 = 88;

// 浮点型
let y = 0.5;
let y: f64 = 0.5;

// 布尔型
let is_girl = false;
let is_boy: bool = true;

// 字符型
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';

3. 复合数据类型

Rust 有两个基本的复合数据类型,一个是元组,一个是数组。元组是固定大小,可以将不同类型的数据组织到一起的数据类型。数据与其他编程语言一样,固定大小,只能保存同类型的数据。

Tuple (元组),涉及到的操作有,构建,访问,解构

1
2
3
4
5
6
7
8
let tp = (1, 2, 3, 5.5, "hello", 'A', false);
let tp: (i32, f64, i32) = (10, 3.1, 44); // 如果前面加了数据类型,则后面的数据要与前面的类型一一对应

let x = tp.0; // 访问第0个元素
let y = tp.1; // 访问第1个元素

let (x, y, z) = tp; // 元组解构,可以用这种方式,将元组中的值按索引分别赋值给前面的变量,一一对应
let (x, y, ..) = tp; // 只将前两个元素分别赋值给 x, y 剩余元素忽略

Array (数组)

1
2
3
4
5
6
7
8
9
let month = ["january", "February", "March"];
let week: [&str; 2] = ["Monday", "Tuesday"];

// 格式,let 数组变量名: [数据类型; 数据个数] = [数据1, 数据2, ...]

let day1 = week[0];
let day2 = week[1];

let length = week.len(); // 可以通过 .len() 访问数组的长度

4. 函数

一个函数,有函数名,函数参数,函数返回值等。

1
2
3
4
// 这是一个简单的函数
fn function1() {
println!("hello");
}
1
2
3
4
// 这是一个带参数的函数
fn print_age(age: i32) {
println!("Age: {}", age);
}
1
2
3
4
// 这是一个带返回值的参数
fn sum(a: i32, b: i32) -> i32 {
return a + b;
}
1
2
3
4
// 这是Rust中通常带有返回值的函数
fn sum(a: i32, b: i32) -> i32 {
a + b
}

上面的函数中,我们没有使用 return,而是直接 a + b,但是结尾没有分号。在 Rust 中,有语句和表达式两个概念,语句简单理解为普通的代码。而表达式,是一段经过计算,会产生一个值的语句,结尾没有分号。如果一个表达式在一个作用域的最后,则这个表达式的结果,就是返回值。

1
2
3
4
5
let x = { 5 + 3 };

fn square(x: i32) -> i32 {
x * x
}

控制语句

分支语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let number = 3;

// if else
if number % 2 == 0 {
println!("state 1");
} else if number % 3 == 0 {
println!("state 2");
} else {
println!("state 3");
}

// if in let
let is_girl = false;
let sign = if is_girl { 0 } else { 1 };

循环语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// loop
loop {
println!("这是一个死循环");
}

// 从循环中返回一个值
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};

// result 的值为20
println!("result: {}", result);


// while
let mut number = 3;
while number != 0 {
println!("{}", number);
number -= 1;
}

let array = [10, 20, 30, 40, 50];
let mut index = 0;
while index < array.len() {
println!("index: {}, Value: {}", index, array[index]);
index += 1;
}

for element in array.iter() {
println!("value: {}", element);
}

// 打印出 1,2,3 不包含结尾数字
for i in (1..4) {
println!("{}", i);
}

// 打印出 1,2,3,4 包含结尾数字
for i in (1..=4) {
println!("{}", i);
}

// 倒着打印,3,2,1
for i in (1..4).rev() {
println!("{}", i);
}

// 倒着打印 4,3,2,1
for i in (1..=4).rev() {
println!("{}", i);
}