Skip to content

语言学习

1.命名空间

Rust 用 模块(mod)use 实现命名空间,避免命名冲突

rust
// 定义一个命名空间(模块)
mod my_module {
    // 模块内的函数,需要 pub 才能外部访问
    pub fn hello() {
        println!("你好,来自 my_module!");
    }

    // 子命名空间
    pub mod sub_module {
        pub fn add(a: i32, b: i32) -> i32 {
            a + b
        }
    }
}

// 引入命名空间(相当于 using namespace)
use my_module::sub_module;

fn main() {
    my_module::hello(); // 直接调用模块函数
    println!("1+2={}", sub_module::add(1, 2)); // 调用子模块
}

2.变量声明 + 赋值

Rust 变量默认不可变,这是 Rust 最大的特点之一

rust
fn main() {
    // 1. 不可变变量(默认),不能二次赋值
    let a = 10;
    println!("不可变变量 a = {}", a);

    // 2. 可变变量(必须加 mut)
    let mut b = 20;
    b = 30; // 允许修改
    println!("可变变量 b = {}", b);

    // 3. 常量(必须指定类型,编译期确定值)
    const PI: f64 = 3.14159;
    println!("常量 PI = {}", PI);

    // 4. 类型注解(手动指定类型)
    let c: i32 = 100;
    let name: &str = "Rust";

    // 5. 变量遮蔽(同名覆盖,允许修改变量类型)
    let x = 5;
    let x = x + 1; // 合法,创建新变量
    let x = "hello"; // 甚至可以改类型!
    println!("遮蔽后的 x = {}", x);
}

3.条件判断(if /else if /else)

Rust 没有三元运算符,但 if 可以当表达式使用(直接赋值)。Rust 中 if 是表达式,不是语句!意味着:if 可以直接返回值,赋值给变量

rust
let age = 20;

// 基础条件判断
if age >= 18 {
    println!("成年");
} else if age >= 12 {
    println!("青少年");
} else {
    println!("儿童");
}

// if 作为表达式(直接赋值)
let status = if age >= 18 { "成年" } else { "未成年" };
println!("状态:{}", status);

//if let(只关心成功)
if let Ok(value) = check_positive(20) {
    println!("成功:{}", value);
}

// 条件必须是 bool 类型,Rust 不允许数字当条件!
// if 1 { ... } 报错!

4.循环结构(loop /while/for)

Rust 有 3 种循环,功能完全覆盖所有场景。

无限循环 loop

rust
loop {
    i += 1;
    if i == 3 {
        println!("继续");
        continue; // 跳过本次
    }
    if i == 5 {
        println!("退出循环");
        break; // 退出循环
    }
    println!("loop: {}", i);
}

条件循环 while

rust
let mut i = 0;
while i < 3 {
    println!("while: {}", i);
    i += 1;
}

遍历循环 for(最常用)

rust
// 遍历范围 1~4
for i in 1..5 {
    println!("for 范围: {}", i);
}

// 遍历数组
let arr = ["苹果", "香蕉", "橙子"];
for fruit in arr {
    println!("水果: {}", fruit);
}

特殊语法

①模式匹配 match(超级强大)

相当于 switch

rust
let num = 2;
match num {
    1 => println!("一"),
    2 => println!("二"),
    3 | 4 => println!("三或四"),
    _ => println!("其他"), // 必须覆盖所有情况
}

// 同时处理成功 + 失败:match(最完整)
match check_positive(30) {
    Ok(v) => println!("成功:{}", v),
    Err(e) => println!("错误:{}", e),
}

② 元组(Tuple)

可以存不同类型的数据,固定长度。

rust
// 定义元组
let person = ("张三", 18, true);
// 解构赋值
let (name, age, is_student) = person;
println!("{},{}岁,学生:{}", name, age, is_student);

③ 所有权 & 引用(Rust 核心)

let s1 = String::from("hello");
let s2 = &s1; // 引用(借用),不转移所有权

println!("s1: {}, s2: {}", s1, s2); // 都能用!

④ 函数返回值

Rust 函数最后一行不加 ; 就是返回值,不用写 return。

fn add(a: i32, b: i32) -> i32 {
    a + b // 无分号 = 返回值
}

fn main() {
    println!("3+5={}", add(3,5));
}

成功 / 失败结果封装:Result<T, E>

这是 Rust 官方标准的成功 / 失败封装,所有项目必用!

rust
// 定义一个函数:成功返回数字,失败返回字符串
fn check_positive(n: i32) -> Result<i32, String> {
    if n > 0 {
        Ok(n) // 成功:用 Ok() 包裹
    } else {
        Err("数字必须大于 0".to_string()) // 失败:用 Err() 包裹
    }
}

fn main() {
    let result = check_positive(10);

    // 使用 match 处理成功/失败
    match result {
        Ok(value) => println!("成功:{}", value),
        Err(err) => println!("失败:{}", err),
    };
}

成功 / 失败(Result)、空值(Option)

Cargo.toml文件

1. 先记住:Rust 统一的成功 / 失败封装

rust

运行

Result<T, E>
    Ok(T)    成功
    Err(E)   失败

Option<T>
    Some(T)  有值
    None     空值

所有错误处理都是围绕这两个枚举。


2. unwrap () —— 最简单但最粗暴

成功就返回值,失败直接崩溃(panic)

适合:测试、示例、你确定一定不会失败的情况。

rust

运行

let r: Result<i32, String> = Ok(100);
let v = r.unwrap(); // 100

let e: Result<i32, String> = Err("错了".into());
e.unwrap(); // 程序直接崩溃

3. expect ("提示") —— 比 unwrap 好,带错误信息

崩溃时会打印你写的提示信息,生产代码推荐用这个代替 unwrap

rust

运行

let r: Result<i32, String> = Err("读取文件失败".into());
r.expect("读取配置文件时出错");

崩溃信息会显示:

plaintext

读取配置文件时出错: 读取文件失败

4. ? 运算符 —— Rust 最优雅、最常用

遇到错误直接返回错误,不崩溃!

只能用在返回 Result / Option 的函数里

rust

运行

fn foo() -> Result<i32, String> {
    let num = bar()?; // 如果 bar() 返回 Err,直接返回给调用者
    Ok(num)
}

fn bar() -> Result<i32, String> {
    Ok(10)
}

一句话:

? = 自动 match + 自动返回错误


5. 完整实战示例(最常用写法)

你复制就能跑,这就是真实 Rust 项目写法:

rust

运行

// 可能成功/失败的函数
fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        return Err("除零错误".to_string());
    }
    Ok(a / b)
}

// 使用 ? 自动传播错误
fn calc() -> Result<i32, String> {
    let a = divide(10, 2)?;
    let b = divide(20, 5)?;
    Ok(a + b)
}

fn main() {
    // 1. expect 用法
    divide(10, 2).expect("计算失败");

    // 2. match 完整处理
    match calc() {
        Ok(v) => println!("结果: {}", v),
        Err(e) => println!("错误: {}", e),
    }

    // 3. if let 只处理成功
    if let Ok(v) = divide(10, 2) {
        println!("成功: {}", v);
    }
}

6. 快速选择指南(背这个就够)

表格

语法用途推荐场景
unwrap()成功返回,失败崩溃测试、示例
expect(msg)成功返回,崩溃带提示小工具、脚本、确定不会错
?自动返回错误90% 项目代码首选
match完整处理成功 / 失败必须处理错误时
if let只关心成功简单逻辑

7. 终极一句话总结

  • unwrap/expect:简单但会崩溃
  • ?:优雅不崩溃,项目必备
  • Result + ? 是 Rust 错误处理的标准组合

错误处理三神器(必背)

rust

运行

val.unwrap();       // 成功返回,失败崩溃
val.expect("信息"); // 失败带提示
val?;               // 自动返回错误(项目首选)

8. 结构体 Struct

rust

运行

struct User { name: String }
let u = User { name: "张三".into() };

9. 向量 Vec(动态数组)

rust

运行

let mut v = vec![1,2,3];
v.push(4);

10. 字符串 String

rust

运行

let s = String::from("hello");
let s2 = &s; // 引用(不转移所有权)

上次更新时间:

最近更新