# 变量
# 变量的可变性
- 声明变量使用 let 关键字
- 默认情况下,变量是不可变的(immutable)
- 使用 let mut 声明变量,就可以声明可变的(mutable)变量
# 常量与不可变变量
- 不可以使用 mut,常量永远不可变的
- 声明常量使用 const,必须手工指定类型
- 常量可以在任何作用域内声明,包括全局作用域
- 常量只可以绑定到常量表达式,无法绑定到函数的调用结果或只能在运行时才能计算出来的值
- 在程序运行期间,常量在其声明的作用域内一直有效
- 命名规范,全大写字母,每个单词下划线分开
| |
| |
| const MAX_SIZE : u32 = 10_000; |
| |
| fn main() { |
| const MAX_SIZE : u32 = 10_000; |
| } |
# shadowing (隐藏)
- 可以使用相同的名字定义新的变量,新的变量会隐藏之前声明的同名变量
- 在后续的代码中,这个变量名就表示新的变量
- 新的变量类型可以不同
| fn main() { |
| |
| let spaces = " "; |
| |
| let spaces = spaces.len(); |
| } |
# 数据类型
rust 能自动推断类型,如果推出多个类型,则需要手工指定类型
# 标量类型
- 整数
- 浮点
- 布尔
- 字符
# 整数类型
- 无符号以 u 开头;有符号以 i 开头
- 有符号范围:−2n−1 到 2n−1−1
- 无符号范围:0 到 2n−1
- isize 和 usize 由系统架构所决定
| 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 |
# 整数字面值
- 除了 byte 类型外,所有的数值字面值都允许使用类型后缀
例如:57u8 - 整数默认类型是:i32
- i32 整体速度很快,即使在 64 位系统
| Number Literals | Example |
|---|
| Decimal | 98_222 |
| Hex | 0xff |
| Octal | 0o77 |
| Binary | 0b1111_0000 |
| Byte (u8 only) | b'A' |
# 整数溢出
- 调试模式下编译,rust 会检查,运行时就会 panic
- 发布模式编译,rust 不会检查导致的 panic 整数溢出
- 如果溢出发生,rust 会执行 “环绕” 操作
# 浮点类型
- f32,32 位 单精度
- f64,64 位 双精度
- 使用 IEEE-754 标准表达
- 默认 f64 类型
# 布尔类型
- 一个字节大小
- 符号是 bool
# 字符类型
- char 类型
- 占用 4 个字节大小
- 使用 Unicode 标量值:多国文字、emoji 表情
- 范围:U+0000 到 U+D7FF;U+E000 到 U+10FFFF
| fn main() { |
| let x = 'z'; |
| let y: char = 'Ƶ'; |
| let z = '😂'; |
| } |
# 复合类型
- 元组(tuple),多个类型的集合,长度固定
- 数值,同种类型的集合,长度固定
# tuple
| fn main() { |
| let tup: (i32, f64, u8) = (500, 6.4, 1); |
| |
| println!("{}, {}, {}", tup.0, tup.1, tup.2); |
| |
| |
| let (x, y, z) = tup; |
| println!("{}, {}, {}", x, y, z); |
| } |
# 数组
数组没有 vector 灵活
| fn main() { |
| let a = [1, 2, 3, 4, 5]; |
| } |
# 数组的类型
数组的类型以这种形式表示:[类型;长度]
例如: let a: [i32; 5] = [1, 2, 3, 4, 5];
如果数组每个元素值都相同,可以:let a = [3; 5];
它就相当于:let a = [3, 3, 3, 3, 3]
# 访问数组元素
rust 不允许访问数组外的地址内存
# 函数
- 使用 fn 关键字
- 使用 snake_case 命名方式
| fn main() { |
| another_function(5); |
| } |
| |
| fn another_function(x: i32) { |
| println!("the value of x is: {}", x); |
| } |
# 函数体中语句和表达式
- 函数体由一系列语句组成,可选的由一个表达式结束
- rust 是一个基于表达式的语言
- 语句是执行一些动作的指令
- 表达式会计算产生一个值
- 函数的定义也是语句
- 语句不返回值,所以不可以使用 let 将一个语句赋值给一个变量
| fn main() { |
| let x = 5; |
| let y = { |
| let x = 1; |
| |
| |
| x + 3 |
| }; |
| |
| |
| |
| println!("The value of y is: {}", y); |
| } |
# 函数的返回值和注释
- 在 -> 符号后面声明函数返回值类型,但是不可以为返回值命名
- 在 rust 里面,返回值就是函数体里面最后一个表达式的值
- 如果要提前返回,需要使用 return 关键字,并指定一个值
| |
| fn plus_five(x: i32) -> i32 { |
| x + 5 |
| } |
| |
| |
| lalalala */ |
| fn main() { |
| |
| let x = plus_five(6); |
| println!("The value of x is: {}", x); |
| } |
# 控制流
# if 表达式
- 与条件相关联的代码块叫做分支(arm)
- 表达式必须是一个 bool 类型的,没有隐式转换
| fn main() { |
| let number = 3; |
| |
| if number < 5 { |
| println!("condition was less than 5."); |
| } else if number > 10 { |
| println!("condition was greater than 10."); |
| } else { |
| println!("condition was [5, 10]."); |
| } |
| } |
# 如果多个 else if 条件,建议用 match 重构
# 在 let 语句中使用 if
if 是一个表达式,因此可以放在 let 语句中等号右边。
| fn main() { |
| let condition = true; |
| let number = if condition { 5 } else { 6 }; |
| println!("The value of number is: {}", number); |
| } |
# 循环
rust 提供 3 种循环:loop,while 和 for
# loop
| fn main() { |
| let mut counter = 0; |
| |
| let result = loop { |
| counter += 1; |
| |
| if counter == 10 { |
| break counter * 2; |
| } |
| }; |
| |
| println!("The result is: {}", result); |
| } |
# while
| fn main() { |
| let mut counter = 3; |
| while counter != 0 { |
| println!("{}", counter); |
| counter = counter - 1; |
| } |
| println!("LIFTOFF"); |
| } |
# for
这是最简洁,最安全的数组遍历,因此这种写法最常用
| fn main() { |
| let a = [10, 20, 30, 40, 50]; |
| |
| for element in a.iter() { |
| println!("The value is: {}", element); |
| } |
| } |
# Range
Range 生成左闭右开的范围,rev () 可以倒过来。
| fn main() { |
| for number in (1..4).rev() { |
| println!("{}", number); |
| } |
| println!("LIFTOFF"); |
| } |