Common Programming Concepts

Comment

1
2
3
4
5
// 单行注释

/*
多行注释
*/

Variables and Mutability

let

$rust$ 基本变量默认不可变

使用 $let$ 关键字声明变量

1
2
3
4
let x = 5;
println!("x = {x}");// 输出 x = 5

// x = 6; // Error! cannot assign twice to immutable variable

也可以显示声明变量类型

格式 data_name: type

1
2
let x: i32 = 5;
println!("x = {x}");// 输出 x = 5

变量名小写,大写 $warning$ 警告!

1
2
3
4
5
6
7
8
9
let X = 5;
println!("{}", X);

// warning: variable `X` should have a snake case name
/*
help: convert the identifier to snake case (notice the capitalization): `x`
|
= note: `#[warn(non_snake_case)]` on by default
*/

mut

使用 $mut$ 关键字表示变量可变

1
2
3
4
let mut y = 5;
println!("y = {y}");// y = 5
y = 6;
println!("y = {y}");// y = 6

const

使用 $const$ 关键字表明常量 $(constants)$

必须显示声明常量类型

1
2
const YEAR : i32 = 2024;
println!("YEAR = {YEAR}");

常量名一般全部大写,小写 $warning$ 警告!

1
2
3
4
5
6
7
8
9
const Year : i32 = 2024;
println!("YEAR = {Year}");

// constant `Year` should have an upper case name
/*
help: convert the identifier to upper case: `YEAR`
|
= note: `#[warn(non_upper_case_globals)]` on by default
*/

shadowing

变量名与前面变量名相同,后面数据覆盖前面

1
2
3
4
5
6
7
8
9
10
11
let s = 5;
println!("s = {s}");// s = 5
let s = s + 1;// 覆盖前面的内容
println!("s = {s}");// s = 6
let s = s * 2;
println!("s = {s}");// s = 12

let s = " ";
println!("s = {s}");// s =
let s = s.len();// 类型可变
println!("s = {s}");// s = 4

吐槽:感觉 $shadowing$ 会造成错误,为什么不直接报错,不小心用了相同名字,前面数据就会被覆盖,这个设计感觉没用

Data Types

Integer Types

Length Signed Unsigned
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
arch isize usize

Integer Literals in Rust

Number literals Example
Decimal 98_222
Hex 0xff
Octal 0o77
Binary 0b1111_0000
Byte (u8 only) b'A'

数据 $overflow$ 会导致 $error$

1
2
3
4
5
6
7
8
9
10
11
12
let x: i8 = 100;
let y: i8 = 100;
let z: i8 = x + y;
println!("{}", z);

// i8 [-127, 128]
/*
error: this arithmetic operation will overflow
attempt to compute `100_i8 + 100_i8`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default
*/

Floating-Point Types

Length Type
32-bit f32
64-bit f64

Numeric Operations

$+ \quad \quad - \quad \quad * \quad \quad / \quad \quad %$

$+= \quad -= \quad *= \quad /= \quad %=$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// addition
let sum = 5 + 10;

// subtraction
let difference = 95.5 - 4.3;

// multiplication
let product = 4 * 30;

// division
let quotient = 56.7 / 32.2;
let truncated = -5 / 3; // Results in -1

// remainder
let remainder = 43 % 5;

应该和 $C++$ 是一样的

The Boolean Type

1
2
3
let t = true;
let f: bool = false;// with explicit type annotation
println!("{t} {f}");// true false

The Character Type

1
2
3
4
let c = 'z';
let z: char = 'ℤ'; // with explicit type annotation
let heart_eyed_cat = '😻';
println!("{c} {z} {heart_eyed_cat}");// z Z 😻

Compound Types

Tuple

元组内数据类型可以不同

可以取出来访问,或用下标访问 data_name.index

1
2
3
4
let x: (i32, f32, bool) = (1, 2.0, false);
let (a, b, c) = x;
println!("{a} {b} {c}");
println!("{} {} {}", x.0, x.1, x.2);

越界会 $Error!$

1
2
println!("{} {} {}", x.0, x.1, x.3);
// error[E0609]: no field `3` on type `(i32, f32, bool)`

直接打印元组

1
2
3
4
println!("{x}");// Error
/*
error[E0277]: `(i32, f32, bool)` doesn't implement `std::fmt::Display`
*/

Array

类型必须一样

使用 [] 来表示

1
2
3
let x = [1, 2, 3, 4, 5];
// [type; size]
let x: [i32; 5] = [1, 2, 3, 4, 5];// with explicit type annotation

声明相同数据的数组

1
2
// [val; size] init with same val
let x = [0; 5];

注意 [] 内是 ;

访问数组元素,使用 data_name[index]

1
2
println!("{}", x[0]);
println!("{}", x[5]);// this operation will panic at runtime index out of bounds: the length is 5 but the index is 5

Functions

使用关键字 $fn$ 来声明函数

不需要像 $C++$ 一样先声明后调用

1
2
3
fn fn_name(Parameters) -> type {

}

-> type 可不写

例如

1
2
3
4
5
println!("{}", test(10));

fn test(n: i32) -> i32 {
return n;
}

这样也可

1
2
3
4
5
6
7
fn test(n: i32) -> i32 {
// expression
n// 注意无;
}

// 若添加 ;
// expected `i32`, found `()`

函数名小写,大写 $warning$ 警告!

1
2
3
4
5
6
7
8
9
10
fn TEST(n: i32) -> i32 {
n
}

//warning: function `TEST` should have a snake case name
/*
help: convert the identifier to snake case: `test`
|
= note: `#[warn(non_snake_case)]` on
*/

Control Flow

if

$if$ 后条件必须为 $bool$ 类型!!!

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

if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}

if number {
println!("condition was true");
} else {
println!("condition was false");
}

// error[E0308]: mismatched types
// expected `bool`, found integer

多条件用 $&&$ 或 $||$ 连接

1
2
3
4
5
6
7
let number = 3;

if 3 < number && number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}

$else \ if$ 使用

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

if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}

let + if

$if$ 和 $else$ 后的类型必须一样

有点像三目运算符复制

1
2
3
4
5
6
7
let condition = true;
let number = if condition { 5 } else { 6 };

println!("The value of number is: {number}");

let number = if condition { 5 } else { "six" };
// expected integer, found `&str

loop

一直循环

break 跳出循环,continue 继续下一次循环

1
2
3
loop {
println!("again!");
}// 一直输出 again

while

基本形式

1
while condition {}

例如

1
2
3
4
while x > 0 {
x -= 1;
println!("{x}");
}

for

基本形式

1
for x in item {}

例如

1
2
3
for x in [3; 5] { // 产生长度为 5 的全是 3 的数组
println!("{x}");
}
1
2
3
for i in (1..4) { // (l..r) 表示区间 [1, 4) 不含 4
println!("{i}");
}

以上就是 $Rust$ 的基本概念

个人感想:$Rust$ 的语法规则非常严格,但是有一些没必要的语法糖。

参考 The Rust Programming Language

更多内容参考我的 Blog