变量与基本类型
学习目标
- 理解
let绑定和可变性 - 掌握 Rust 的基本数据类型
- 理解类型推断和类型转换
- 掌握
const和static的区别
核心概念
变量绑定与可变性
fn main() {
let x = 5; // 不可变(默认)
// x = 6; // ❌ 编译错误:不能修改不可变变量
let mut y = 5; // 可变
y = 6; // ✅
let x = "hello"; // 遮蔽(shadowing):重新绑定同名变量,可以换类型
println!("{}", x); // "hello"
}
可变 vs 遮蔽:
let mut x = 5;
x = x + 1; // 修改同一个绑定,类型不能变
let x = x + 1; // 创建新绑定,类型可以变
let x = x.to_string(); // 从 i32 变成 String
基本类型
| 类型 | 示例 | 说明 |
|---|---|---|
i8/i16/i32/i64/i128/isize | 42, -1 | 有符号整数 |
u8/u16/u32/u64/u128/usize | 42, 0xff | 无符号整数 |
f32/f64 | 3.14, 2.0 | 浮点数 |
bool | true, false | 布尔 |
char | 'a', '中' | Unicode 字符(4 字节) |
&str | "hello" | 字符串切片 |
String | String::from("hi") | 堆分配字符串 |
整数溢出
let x: u8 = 255; // u8 最大值
// let y: u8 = x + 1; // ❌ debug 模式 panic,release 模式回绕为 0
// 安全的溢出处理
let y = x.wrapping_add(1); // 0(回绕)
let y = x.checked_add(1); // None(返回 Option)
let y = x.overflowing_add(1); // (0, true)(返回结果和是否溢出)
数字字面量
let million = 1_000_000; // 下划线分隔,可读性
let hex = 0xff; // 十六进制
let octal = 0o77; // 八进制
let binary = 0b1111_0000; // 二进制
let byte = b'A'; // 字节字面量(u8)
let f: f64 = 3.14; // 浮点数默认 f64
let f: f32 = 3.14_f32; // 显式 f32
类型转换
let x: i32 = 42;
let y: f64 = x as f64; // 显式转换用 as
let a: u8 = 255;
let b: u16 = a as u16; // 小类型 → 大类型(安全)
let c: u8 = 300 as u8; // 大类型 → 小类型(截断,255 → 44)
const 和 static
const MAX_SIZE: usize = 1024; // 编译期常量,内联
static APP_NAME: &str = "my_app"; // 全局变量,有固定地址
static mut COUNTER: u32 = 0; // 可变 static(unsafe 访问)
unsafe {
COUNTER += 1;
}
实践练习
练习 1:类型推断
不指定类型,让编译器推断:
fn main() {
let a = 42; // 什么类型?
let b = 3.14; // 什么类型?
let c = true; // 什么类型?
let d = '中'; // 什么类型?
let e = "hello"; // 什么类型?
// 用 {:?} 打印类型(需要加一行提示)
println!("a: i32, b: f64, c: bool, d: char, e: &str");
}
练习 2:遮蔽练习
fn main() {
let x = 5;
let x = x + 1; // x = ?
let x = x * 2; // x = ?
println!("{}", x); // 输出什么?
}
练习 3:类型转换
fn main() {
let temperature_f: f64 = 98.6;
// 转换为摄氏温度: C = (F - 32) * 5/9
let temperature_c: f64 = (temperature_f - 32.0) * 5.0 / 9.0;
println!("{}°F = {}°C", temperature_f, temperature_c);
// 把结果转为整数
let temp_int = temperature_c as i32;
println!("约 {}°C", temp_int);
}
常见错误
1. 误用不可变变量
let count = 0;
count += 1; // ❌ cannot assign twice to immutable variable
// ✅
let mut count = 0;
count += 1;
2. 类型不匹配
let x: i32 = 5;
let y: f64 = 3.14;
let z = x + y; // ❌ cannot add `f64` to `i32`
// ✅
let z = x as f64 + y;
3. 整数溢出 panic
let x: u8 = 255;
let y = x + 1; // ❌ debug 模式 panic
// ✅ 使用安全方法
let y = x.wrapping_add(1);
小结
| 要点 | 说明 |
|---|---|
let | 不可变绑定(默认) |
let mut | 可变绑定 |
let x = ...(同名) | 遮蔽,可以换类型 |
as | 显式类型转换 |
const | 编译期常量 |
_ | 数字字面量分隔符 |
Rust 的默认不可变设计是刻意的——强制你思考哪些值需要修改。