Rust函数与流程控制——构建逻辑清晰的系统级程序

第3篇:Rust函数与流程控制------构建逻辑清晰的系统级程序

一、学习目标与重点

1.1 学习目标

  1. 掌握函数定义与调用:理解Rust函数的完整语法,包括参数传递、返回值类型(单值、元组、Option/Result)
  2. 精通流程控制语句:熟练运用条件判断(if/else、match)和循环(loop、while、for),掌握其高级用法
  3. 理解模式匹配:深入学习match表达式的模式匹配语法,包括常量匹配、变量绑定、通配符等
  4. 实战流程控制:结合真实场景编写简单但实用的代码,如计算器、猜数字游戏、待办事项管理系统
  5. 优化代码逻辑:通过函数抽象和流程控制优化代码的可读性和可维护性

1.2 学习重点

💡 三大核心难点

  1. match表达式的模式匹配规则(包括嵌套匹配、守卫条件)
  2. 函数的返回值类型推断早期返回(?运算符)
  3. 循环的标签语法break/continue的精确控制

⚠️ 三大高频错误点

  1. match表达式的完整性检查失败(缺少匹配分支)
  2. if/else表达式的返回值类型不一致(Rust的if/else是表达式,可以赋值给变量)
  3. 函数参数的所有权转移引用传递混淆

二、Rust函数详解

2.1 函数的基本定义与调用

Rust的函数定义必须使用fn关键字,函数名遵循蛇形命名法(小写字母+下划线),参数和返回值类型必须明确(除了省略单位类型())。

⌨️ 函数基本定义与调用示例

rust 复制代码
// 简单函数(无参数,无返回值)
fn say_hello() {
    println!("Hello, Rust!");
}

// 有参数的函数(参数类型明确)
fn add(x: i32, y: i32) -> i32 {  // -> i32表示返回值类型是i32
    x + y  // 没有分号,表明这是表达式,返回结果
}

// 有参数的函数(带分号的语句)
fn subtract(x: i32, y: i32) -> i32 {
    let result = x - y;
    result  // 必须是表达式,没有分号
}

fn main() {
    // 调用无参数函数
    say_hello();

    // 调用有参数函数
    let sum = add(10, 5);
    println!("10 + 5 = {}", sum);  // 15

    let difference = subtract(10, 5);
    println!("10 - 5 = {}", difference);  // 5
}

2.2 函数的参数传递

Rust的函数参数传递有三种方式

  1. 所有权转移:参数直接获取值的所有权,调用后原变量无法访问
  2. 不可变引用传递:参数获取值的不可变引用,调用后原变量仍可访问(最常用)
  3. 可变引用传递:参数获取值的可变引用,调用后原变量可以被修改

⌨️ 参数传递方式示例

rust 复制代码
// 所有权转移
fn takes_ownership(s: String) {
    println!("takes_ownership:{}", s);
}

// 不可变引用传递
fn borrows_ownership(s: &String) {
    println!("borrows_ownership:{}", s);
}

// 可变引用传递
fn mutates_ownership(s: &mut String) {
    s.push_str(", Rust!");
}

fn main() {
    // 所有权转移
    let s1 = String::from("Hello");
    takes_ownership(s1);
    // println!("s1:{}", s1);  // 编译错误:s1的所有权已转移

    // 不可变引用传递
    let s2 = String::from("World");
    borrows_ownership(&s2);
    println!("s2:{}", s2);  // World(所有权未转移)

    // 可变引用传递
    let mut s3 = String::from("Rust");
    mutates_ownership(&mut s3);
    println!("s3:{}", s3);  // Rust, Rust!(值被修改)
}

2.3 函数的返回值类型

Rust的函数返回值类型非常灵活,包括:

  1. 单值返回:返回一个基本类型或自定义类型的值
  2. 元组返回:返回多个值的组合(用于需要返回多个结果的场景)
  3. Option返回:表示可能返回值的场景(Some(T)表示有值,None表示无值)
  4. Result<T, E>返回:表示可能返回值或错误的场景(Ok(T)表示成功,Err(E)表示失败)

⌨️ 函数返回值类型示例

rust 复制代码
// 单值返回(基本类型)
fn square(x: i32) -> i32 {
    x * x
}

// 单值返回(自定义类型)
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn get_origin() -> Point {
    Point { x: 0, y: 0 }
}

// 元组返回(多个值的组合)
fn calculate_rectangle(width: u32, height: u32) -> (u32, u32) {
    let area = width * height;
    let perimeter = (width + height) * 2;
    (area, perimeter)
}

// Option<T>返回(可能返回值)
fn find_max(numbers: &[i32]) -> Option<i32> {
    if numbers.is_empty() {
        None
    } else {
        let mut max = numbers[0];
        for &num in numbers.iter() {
            if num > max {
                max = num;
            }
        }
        Some(max)
    }
}

// Result<T, E>返回(可能返回值或错误)
fn divide(x: i32, y: i32) -> Result<i32, String> {
    if y == 0 {
        Err(String::from("除数不能为0"))
    } else {
        Ok(x / y)
    }
}

fn main() {
    // 单值返回(基本类型)
    let square_result = square(5);
    println!("5的平方:{}", square_result);  // 25

    // 单值返回(自定义类型)
    let origin = get_origin();
    println!("原点坐标:{:?}", origin);  // Point { x: 0, y: 0 }

    // 元组返回(多个值的组合)
    let (area, perimeter) = calculate_rectangle(10, 5);
    println!("面积:{},周长:{}", area, perimeter);  // 面积:50,周长:30

    // Option<T>返回(可能返回值)
    let numbers1 = [1, 3, 5, 7, 9];
    if let Some(max) = find_max(&numbers1) {
        println!("numbers1的最大值:{}", max);  // 9
    } else {
        println!("numbers1是空数组");
    }

    let numbers2: [i32; 0] = [];
    if let Some(max) = find_max(&numbers2) {
        println!("numbers2的最大值:{}", max);
    } else {
        println!("numbers2是空数组");  // 会执行这条
    }

    // Result<T, E>返回(可能返回值或错误)
    match divide(10, 2) {
        Ok(result) => println!("10 / 2 = {}", result),  // 5
        Err(e) => println!("错误:{}", e),
    }

    match divide(10, 0) {
        Ok(result) => println!("10 / 0 = {}", result),
        Err(e) => println!("错误:{}", e),  // 会执行这条
    }
}

2.4 函数的高级用法

2.4.1 函数作为参数

Rust支持函数作为参数 ,可以实现函数式编程的特性。

⌨️ 函数作为参数示例

rust 复制代码
// 定义一个接受函数作为参数的函数
fn apply_function<F>(x: i32, f: F) -> i32
where
    F: Fn(i32) -> i32,  // 泛型约束:F必须是一个接受i32参数并返回i32的函数
{
    f(x)
}

// 定义几个简单的函数
fn double(x: i32) -> i32 {
    x * 2
}

fn triple(x: i32) -> i32 {
    x * 3
}

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

fn main() {
    let x = 5;

    let double_result = apply_function(x, double);
    println!("{}的两倍:{}", x, double_result);  // 10

    let triple_result = apply_function(x, triple);
    println!("{}的三倍:{}", x, triple_result);  // 15

    let square_result = apply_function(x, square);
    println!("{}的平方:{}", x, square_result);  // 25
}
2.4.2 函数作为返回值

Rust支持函数作为返回值 ,可以实现闭包捕获环境变量的特性。

⌨️ 函数作为返回值示例

rust 复制代码
// 定义一个返回函数的函数
fn get_multiplier(factor: i32) -> impl Fn(i32) -> i32 {
    move |x| x * factor  // 使用move关键字捕获factor
}

fn main() {
    let double = get_multiplier(2);
    let triple = get_multiplier(3);

    println!("5的两倍:{}", double(5));  // 10
    println!("5的三倍:{}", triple(5));  // 15
}

三、Rust流程控制详解

3.1 条件判断

3.1.1 if/else语句

if/else语句是Rust中最基本的条件判断语句,条件表达式必须是bool类型(Rust不支持非bool类型的条件判断)。

⌨️ if/else语句示例

rust 复制代码
// 简单的if/else语句
let x = 5;
if x > 0 {
    println!("x是正数");
} else if x < 0 {
    println!("x是负数");
} else {
    println!("x是0");
}

// if/else作为表达式(可以赋值给变量)
let y = 10;
let result = if y > 5 {
    "y大于5"  // 表达式,没有分号
} else {
    "y小于等于5"
};
println!("{}", result);  // y大于5

// 复合条件判断
let a = 10;
let b = 20;
if a > 0 && b > 0 {
    println!("a和b都是正数");
} else if a < 0 || b < 0 {
    println!("a或b是负数");
} else {
    println!("a或b是0");
}

⚠️ if/else表达式的返回值类型

if/else作为表达式时,所有分支的返回值类型必须一致,否则会导致编译错误。

⌨️ if/else表达式返回值类型不一致的错误示例

rust 复制代码
let x = 5;
let result = if x > 0 {
    "正数"  // 类型是&str
} else {
    0  // 类型是i32
};
// 编译错误:if and else have incompatible types
3.1.2 match表达式

match表达式是Rust中最强大的条件判断语句,支持模式匹配,可以匹配各种类型的值,包括整数、字符串、枚举、结构体等。

⌨️ match表达式基本示例

rust 复制代码
// 匹配整数
let x = 5;
match x {
    1 => println!("x是1"),
    2 => println!("x是2"),
    3 | 4 => println!("x是3或4"),  // 多模式匹配
    5..=10 => println!("x在5-10之间"),  // 范围匹配
    _ => println!("x是其他值"),  // 通配符匹配(必须放在最后)
}

// 匹配字符串
let s = "Hello";
match s {
    "Hello" => println!("你好"),
    "World" => println!("世界"),
    _ => println!("其他字符串"),
}

// 匹配枚举
#[derive(Debug)]
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

let direction = Direction::Right;
match direction {
    Direction::Up => println!("向上"),
    Direction::Down => println!("向下"),
    Direction::Left => println!("向左"),
    Direction::Right => println!("向右"),  // 没有通配符,因为枚举的所有值都已匹配
}

⌨️ match表达式的高级用法示例

rust 复制代码
// 变量绑定
let numbers = (1, 2, 3);
match numbers {
    (x, y, z) if x + y > z => println!("x + y > z:{} + {} > {}", x, y, z),  // 使用守卫条件
    (x, y, z) => println!("x + y <= z:{} + {} <= {}", x, y, z),
}

// 嵌套匹配
#[derive(Debug)]
enum Action {
    Move { x: i32, y: i32 },
    Jump(i32),
    Attack,
}

let action = Action::Move { x: 10, y: 5 };
match action {
    Action::Move { x, y } => println!("移动到({}, {})", x, y),
    Action::Jump(height) => println!("跳跃{}个单位", height),
    Action::Attack => println!("攻击"),
}

3.2 循环

3.2.1 loop循环

loop循环是Rust中最简单的循环语句,无限循环,直到遇到break关键字。

⌨️ loop循环示例

rust 复制代码
// 简单的loop循环(计算1-10的和)
let mut sum = 0;
let mut i = 1;
loop {
    sum += i;
    i += 1;
    if i > 10 {
        break;  // 跳出循环
    }
}
println!("1-10的和:{}", sum);  // 55

// loop循环作为表达式(可以返回值)
let mut x = 0;
let result = loop {
    x += 1;
    if x == 5 {
        break x * 2;  // 跳出循环并返回x * 2
    }
};
println!("loop循环返回值:{}", result);  // 10
3.2.2 while循环

while循环是Rust中最常用的循环语句,条件判断在循环开始前,如果条件为true,则执行循环体,否则跳出循环。

⌨️ while循环示例

rust 复制代码
// 简单的while循环(计算1-10的和)
let mut sum = 0;
let mut i = 1;
while i <= 10 {
    sum += i;
    i += 1;
}
println!("1-10的和:{}", sum);  // 55

// 使用while循环遍历数组
let mut numbers = [1, 3, 5, 7, 9];
let mut index = 0;
while index < numbers.len() {
    println!("{}", numbers[index]);
    index += 1;
}
3.2.3 for循环

for循环是Rust中最强大的循环语句,专门用于遍历集合(数组、Vec、字符串、范围等)。

⌨️ for循环示例

rust 复制代码
// 遍历范围(1-10)
let mut sum = 0;
for i in 1..=10 {
    sum += i;
}
println!("1-10的和:{}", sum);  // 55

// 遍历数组
let numbers = [1, 3, 5, 7, 9];
for num in numbers.iter() {
    println!("{}", num);
}

// 遍历字符串的字符
let s = "Rust语言开发";
for c in s.chars() {
    println!("{}", c);
}

// 遍历Vec
let mut vec = vec![10, 20, 30, 40, 50];
for num in &mut vec {
    *num *= 2;  // 使用解引用运算符*修改值
}
println!("Vec的值:{:?}", vec);  // [20,40,60,80,100]

3.3 循环的高级用法

3.3.1 标签语法

Rust支持标签语法,可以给循环添加标签,以便在嵌套循环中精确控制break/continue的行为。

⌨️ 标签语法示例

rust 复制代码
// 标签语法控制break
'outer: loop {
    println!("外层循环开始");
    'inner: loop {
        println!("内层循环开始");
        break 'outer;  // 跳出外层循环
    }
    println!("外层循环结束");  // 不会执行
}

// 标签语法控制continue
'outer: for i in 1..=3 {
    println!("外层循环:{}", i);
    'inner: for j in 1..=3 {
        if j == 2 {
            continue 'outer;  // 跳过外层循环的当前迭代
        }
        println!("内层循环:{}", j);
    }
}
3.3.2 break/continue的高级用法

break关键字可以跳出循环并返回值 ,continue关键字可以跳过循环的当前迭代

⌨️ break/continue的高级用法示例

rust 复制代码
// break跳出循环并返回值
let mut x = 0;
let result = loop {
    x += 1;
    if x == 5 {
        break x * 2;  // 跳出循环并返回x * 2
    }
};
println!("loop循环返回值:{}", result);  // 10

// continue跳过当前迭代
let mut numbers = [1, 3, 5, 7, 9];
for num in numbers.iter() {
    if *num == 5 {
        continue;  // 跳过5
    }
    println!("{}", num);  // 输出1,3,7,9
}

四、真实案例应用

4.1 案例1:简单的计算器

💡 场景分析:需要编写一个简单的计算器,支持加法、减法、乘法、除法四种运算,读取用户输入的操作符和操作数,计算并输出结果。

⌨️ 代码示例

rust 复制代码
use std::io;

// 定义操作符的枚举类型
#[derive(Debug)]
enum Operator {
    Add,
    Subtract,
    Multiply,
    Divide,
}

// 解析操作符的函数
fn parse_operator(input: &str) -> Option<Operator> {
    match input.trim() {
        "+" => Some(Operator::Add),
        "-" => Some(Operator::Subtract),
        "*" => Some(Operator::Multiply),
        "/" => Some(Operator::Divide),
        _ => None,
    }
}

// 解析操作数的函数
fn parse_number(input: &str) -> Option<f64> {
    input.trim().parse().ok()
}

// 计算结果的函数
fn calculate(op: Operator, x: f64, y: f64) -> Result<f64, String> {
    match op {
        Operator::Add => Ok(x + y),
        Operator::Subtract => Ok(x - y),
        Operator::Multiply => Ok(x * y),
        Operator::Divide => {
            if y == 0.0 {
                Err(String::from("除数不能为0"))
            } else {
                Ok(x / y)
            }
        }
    }
}

fn main() {
    println!("简单的计算器");
    println!("----------------");
    println!("支持的操作符:+、-、*、/");
    println!("请输入操作符和两个操作数(用空格分隔,例如:+ 10 5)");

    loop {
        let mut input = String::new();
        io::stdin().read_line(&mut input).expect("读取输入失败");

        let tokens: Vec<&str> = input.trim().split_whitespace().collect();
        if tokens.len() != 3 {
            println!("输入格式错误,请重新输入");
            continue;
        }

        let operator = match parse_operator(tokens[0]) {
            Some(op) => op,
            None => {
                println!("无效的操作符,请重新输入");
                continue;
            }
        };

        let x = match parse_number(tokens[1]) {
            Some(num) => num,
            None => {
                println!("第一个操作数无效,请重新输入");
                continue;
            }
        };

        let y = match parse_number(tokens[2]) {
            Some(num) => num,
            None => {
                println!("第二个操作数无效,请重新输入");
                continue;
            }
        };

        let result = calculate(operator, x, y);
        match result {
            Ok(res) => println!("结果:{:.2}", res),
            Err(e) => println!("错误:{}", e),
        }

        println!("是否继续计算?(输入y继续,输入其他内容结束)");
        let mut choice = String::new();
        io::stdin().read_line(&mut choice).expect("读取输入失败");
        if choice.trim().to_lowercase() != "y" {
            break;
        }
    }

    println!("计算器结束");
}

4.2 案例2:猜数字游戏

💡 场景分析:需要编写一个猜数字游戏,程序随机生成一个1-100之间的整数,用户输入猜测的数字,程序提示猜测过高或过低,直到用户猜中为止。

⌨️ 代码示例

rust 复制代码
use std::io;
use rand::Rng;  // 需要在Cargo.toml中添加rand库的依赖

fn main() {
    println!("猜数字游戏");
    println!("----------------");
    println!("程序将随机生成一个1-100之间的整数");
    println!("请输入你猜测的数字");

    // 生成随机数
    let secret_number = rand::thread_rng().gen_range(1..=100);

    loop {
        let mut guess = String::new();
        io::stdin().read_line(&mut guess).expect("读取输入失败");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("请输入有效的整数");
                continue;
            }
        };

        if guess < 1 || guess > 100 {
            println!("猜测的数字必须在1-100之间");
            continue;
        }

        match guess.cmp(&secret_number) {
            std::cmp::Ordering::Less => println!("猜测过低"),
            std::cmp::Ordering::Greater => println!("猜测过高"),
            std::cmp::Ordering::Equal => {
                println!("恭喜你,猜中了!");
                break;
            }
        }
    }
}

⚠️ 注意:需要在Cargo.toml中添加rand库的依赖:

toml 复制代码
[dependencies]
rand = "0.8.5"

4.3 案例3:待办事项管理系统

💡 场景分析:需要编写一个简单的待办事项管理系统,支持添加待办事项、删除待办事项、查看待办事项、标记待办事项为已完成。

⌨️ 代码示例

rust 复制代码
use std::io;
use std::collections::HashMap;

#[derive(Debug, Clone)]
struct TodoItem {
    id: u32,
    title: String,
    completed: bool,
}

struct TodoList {
    items: HashMap<u32, TodoItem>,
    next_id: u32,
}

impl TodoList {
    // 创建新的待办事项列表
    fn new() -> Self {
        TodoList {
            items: HashMap::new(),
            next_id: 1,
        }
    }

    // 添加待办事项
    fn add_item(&mut self, title: String) {
        let item = TodoItem {
            id: self.next_id,
            title,
            completed: false,
        };
        self.items.insert(self.next_id, item);
        self.next_id += 1;
    }

    // 删除待办事项
    fn delete_item(&mut self, id: u32) -> bool {
        self.items.remove(&id).is_some()
    }

    // 标记待办事项为已完成
    fn mark_completed(&mut self, id: u32) -> bool {
        if let Some(item) = self.items.get_mut(&id) {
            item.completed = true;
            true
        } else {
            false
        }
    }

    // 查看待办事项
    fn list_items(&self) {
        if self.items.is_empty() {
            println!("待办事项列表是空的");
            return;
        }

        println!("待办事项列表");
        println!("----------------");
        println!("ID\t标题\t\t状态");
        println!("----------------");
        for (_, item) in self.items.iter() {
            let status = if item.completed { "已完成" } else { "未完成" };
            println!("{}\t{}\t{}", item.id, item.title, status);
        }
    }
}

fn main() {
    let mut todo_list = TodoList::new();

    loop {
        println!("待办事项管理系统");
        println!("----------------");
        println!("1. 添加待办事项");
        println!("2. 删除待办事项");
        println!("3. 标记待办事项为已完成");
        println!("4. 查看待办事项");
        println!("5. 退出");
        println!("----------------");
        println!("请输入操作编号:");

        let mut choice = String::new();
        io::stdin().read_line(&mut choice).expect("读取输入失败");

        match choice.trim().parse::<u32>() {
            Ok(1) => {
                println!("请输入待办事项的标题:");
                let mut title = String::new();
                io::stdin().read_line(&mut title).expect("读取输入失败");
                todo_list.add_item(title.trim().to_string());
                println!("待办事项添加成功");
            }
            Ok(2) => {
                println!("请输入待办事项的ID:");
                let mut id = String::new();
                io::stdin().read_line(&mut id).expect("读取输入失败");
                match id.trim().parse::<u32>() {
                    Ok(id) => {
                        if todo_list.delete_item(id) {
                            println!("待办事项删除成功");
                        } else {
                            println!("待办事项不存在");
                        }
                    }
                    Err(_) => println!("无效的ID"),
                }
            }
            Ok(3) => {
                println!("请输入待办事项的ID:");
                let mut id = String::new();
                io::stdin().read_line(&mut id).expect("读取输入失败");
                match id.trim().parse::<u32>() {
                    Ok(id) => {
                        if todo_list.mark_completed(id) {
                            println!("待办事项标记为已完成");
                        } else {
                            println!("待办事项不存在");
                        }
                    }
                    Err(_) => println!("无效的ID"),
                }
            }
            Ok(4) => todo_list.list_items(),
            Ok(5) => {
                println!("待办事项管理系统结束");
                break;
            }
            Ok(_) => println!("无效的操作编号"),
            Err(_) => println!("无效的输入"),
        }

        println!();
    }
}

五、常见问题与解决方案

5.1 match表达式缺少匹配分支

问题现象:match表达式的所有分支没有完全覆盖所有可能的情况,导致编译错误。

解决方案:添加一个通配符匹配分支(_),覆盖所有未匹配的情况。

⌨️ 通配符匹配示例

rust 复制代码
let x = 5;
match x {
    1 => println!("x是1"),
    2 => println!("x是2"),
    _ => println!("x是其他值"),  // 通配符匹配,必须放在最后
}

5.2 if/else表达式返回值类型不一致

问题现象:if/else作为表达式时,所有分支的返回值类型不一致,导致编译错误。

解决方案:确保所有分支的返回值类型一致。

⌨️ if/else表达式返回值类型一致的示例

rust 复制代码
let x = 5;
let result = if x > 0 {
    "正数"  // 类型是&str
} else {
    "非正数"  // 类型也是&str
};
println!("{}", result);  // 正数

5.3 函数参数的所有权转移与引用传递混淆

问题现象:函数参数直接获取值的所有权,调用后原变量无法访问,导致编译错误。

解决方案:使用不可变引用传递或可变引用传递,而不是所有权转移。

⌨️ 不可变引用传递示例

rust 复制代码
fn borrows_ownership(s: &String) {
    println!("{}", s);
}

fn main() {
    let s = String::from("Hello");
    borrows_ownership(&s);
    println!("{}", s);  // Hello(所有权未转移)
}

5.4 循环中的变量捕获问题

问题现象:在循环中创建闭包并捕获变量时,可能会导致变量的所有权或生命周期问题。

解决方案:使用move关键字捕获变量,或确保变量的生命周期在闭包使用期间有效。

⌨️ 使用move关键字捕获变量示例

rust 复制代码
fn main() {
    let mut vec = vec![10, 20, 30, 40, 50];
    let mut handles = Vec::new();

    for num in vec.iter() {
        let handle = std::thread::spawn(move || {
            println!("{}", num);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }
}

六、总结与展望

6.1 总结

✅ 掌握了Rust函数的完整语法,包括参数传递、返回值类型(单值、元组、Option/Result)

✅ 精通了流程控制语句,包括条件判断(if/else、match)和循环(loop、while、for)

✅ 深入学习了match表达式的模式匹配语法,包括常量匹配、变量绑定、通配符等

✅ 结合真实场景编写了三个实用的代码案例,如简单的计算器、猜数字游戏、待办事项管理系统

✅ 优化了代码的逻辑,通过函数抽象和流程控制提高了代码的可读性和可维护性

6.2 展望

下一篇文章,我们将深入学习Rust的所有权、借用和生命周期,这是Rust语言的核心内存安全机制,也是最容易让新手困惑的地方。我们将详细讲解所有权的基本概念、借用的规则、生命周期的标注方法,并通过真实场景应用这些知识,编写安全、高效的代码。

相关推荐
liliangcsdn2 小时前
如何使用lambda对python列表进行排序
开发语言·python
源代码•宸2 小时前
Leetcode—404. 左叶子之和【简单】
经验分享·后端·算法·leetcode·职场和发展·golang·dfs
java 乐山3 小时前
c 写一个文本浏览器(1)
c语言·开发语言
windows_63 小时前
MISRA C:2025 规则逐条分析
c语言·开发语言
fie88893 小时前
基于MATLAB的可见光通信(VLC)系统仿真
开发语言·matlab
写代码的【黑咖啡】3 小时前
Python中的lxml:高效XML处理库
xml·开发语言·python
黎雁·泠崖3 小时前
Java字符串高阶:底层原理深剖+经典面试题全解
java·开发语言
你这个代码我看不懂3 小时前
Spring Boot拦截Http请求设置请求头
spring boot·后端·http
清风~徐~来4 小时前
【视频点播系统】环境搭建
开发语言