Rust编程基础课 第2课时:Rust基础语法(变量、数据类型、运算符)

文章目录

第2课时:Rust基础语法(变量、数据类型、运算符)

一、课程目标

  • 掌握Rust变量的定义、声明规则及可变性控制,贴合嵌入式开发场景规范

  • 熟记Rust核心数据类型(标量、复合),明确不同类型在STM32开发中的用途

  • 熟练运用各类运算符(算术、比较、逻辑等),能编写简单的运算逻辑

  • 结合示例练习,规范Rust代码编写格式,规避基础语法错误

二、课程重难点

  • 重点:变量的可变性与不可变性、核心数据类型用法、运算符优先级

  • 难点:变量阴影化的理解与正确使用、复合数据类型(数组、元组)的实操

三、课程内容

3.1 Rust变量

3.1.1 变量声明规则

Rust变量声明使用let关键字,默认是不可变(immutable),这是Rust内存安全的基础,避免意外修改数据导致的异常(尤其适配嵌入式场景)。

语法格式:let 变量名: 数据类型 = 赋值;(数据类型可省略,Rust会自动推导)

3.1.2 不可变与可变性
  • 不可变变量(默认):声明后无法修改值,适合不需要变化的数据(如外设地址、常量参数)。

  • 可变变量:在let后加mut关键字,声明后可修改值,适合需要动态变化的数据(如传感器采集值、计数器)。

3.1.3 变量阴影化(Shadowing)

let关键字重新声明同名变量,新变量会覆盖旧变量,称为阴影化。与可变变量不同,阴影化可以改变数据类型,且旧变量不可再访问。

3.2 Rust核心数据类型

Rust数据类型分为两大类:标量类型(单个值)和复合类型(多个值组合),嵌入式开发中重点关注标量类型和简单复合类型。

3.2.1 标量类型(重点)
  • 整数类型:按位数和符号划分,嵌入式常用u8(无符号8位,适配GPIO电平)、i32(有符号32位,常用计算)、u32(无符号32位,计数器)。

  • 浮点类型:f32(单精度浮点)、f64(双精度浮点),用于传感器浮点数据(如温度、湿度)。

  • 布尔类型:bool,值为truefalse,用于判断逻辑(如按键是否按下、外设是否就绪)。

  • 字符类型:char,单引号包裹,占4字节,用于简单字符显示(如串口打印字符)。

3.2.2 复合类型(基础)
  • 元组(Tuple):固定长度,不同类型值的组合,语法:let 元组名 = (值1, 值2, ...);,适合组合少量相关数据(如坐标、外设状态)。

  • 数组(Array):固定长度,相同类型值的组合,语法:let 数组名: [类型; 长度] = [值1, 值2, ...];,适合存储批量相同类型数据(如传感器采集的多组数据)。

3.3 Rust运算符

运算符用于对数据进行运算,按功能分为4类,重点掌握算术、比较、逻辑运算符,适配嵌入式数据处理场景。

  • 算术运算符:+(加)、-(减)、*(乘)、/(除)、%(取余),用于数值计算(如传感器数据换算)。

  • 比较运算符:==(等于)、!=(不等于)、>(大于)、<(小于)等,用于判断逻辑(如阈值对比)。

  • 逻辑运算符:&&(逻辑与)、||(逻辑或)、!(逻辑非),用于复杂判断(如多条件触发外设)。

  • 赋值运算符:=(赋值)、+=(加赋值)、-=(减赋值)等,用于变量赋值和更新。

3.4 实战演示

结合嵌入式场景,编写简单语法演示代码,验证变量、数据类型和运算符的使用。

四、课堂示例(可直接复制运行)

示例1:变量的不可变、可变性与阴影化

rust 复制代码
// 不可变变量(默认)
let led_pin = 13; // STM32 LED引脚编号,不可修改
// led_pin = 14; // 报错:不可变变量无法修改

// 可变变量
let mut counter = 0; // 计数器,可修改
counter += 1;
println!("计数器值:{}", counter);

// 变量阴影化
let num = 5;
let num = num * 2; // 阴影化,改变值,类型不变
let num = num.to_string(); // 阴影化,改变类型(i32 → String)
println!("阴影化后的num:{}", num);

示例2:数据类型实操(贴合嵌入式)

rust 复制代码
// 标量类型
let gpio_level: u8 = 1; // GPIO高电平(0低电平,1高电平)
let temperature: f32 = 25.5; // 温度传感器采集值(℃)
let is_key_pressed: bool = false; // 按键未按下
let serial_char: char = 'A'; // 串口发送字符

// 复合类型
let sensor_data = (25.5, 60.2); // 元组:(温度,湿度)
let led_states: [bool; 3] = [true, false, true]; // 数组:3个LED的状态

// 打印所有数据
println!("GPIO电平:{}", gpio_level);
println!("温度:{}℃", temperature);
println!("按键状态:{}", is_key_pressed);
println!("串口字符:{}", serial_char);
println!("传感器数据:(温度:{}℃,湿度:{}%)", sensor_data.0, sensor_data.1);
println!("LED状态:{:?}", led_states);

示例3:运算符实操(嵌入式数据处理)

rust 复制代码
// 算术运算:传感器数据换算(ADC采集值→实际电压)
let adc_value: u16 = 1023; // ADC采集最大值(12位ADC)
let voltage: f32 = (adc_value as f32) * 3.3 / 4095.0; // 换算为3.3V电压

// 比较运算:阈值判断(温度超过30℃触发报警)
let temperature = 32.5;
let is_alarm = temperature > 30.0;

// 逻辑运算:多条件判断(按键按下且温度正常)
let is_key_pressed = true;
let is_temp_normal = temperature <= 30.0;
let can_operate = is_key_pressed && is_temp_normal;

println!("ADC采集电压:{:.2}V", voltage);
println!("是否触发温度报警:{}", is_alarm);
println!("是否可操作:{}", can_operate);

五、课后作业(巩固练习)

    1. 编写代码,声明1个不可变变量(存储STM32引脚编号)、1个可变变量(存储计数器),实现计数器自增3次并打印每次结果。
    1. 定义标量类型变量(u8、i32、f32、bool),分别赋值并打印;定义1个元组(存储传感器的温度、湿度、气压),1个数组(存储4个LED的状态),打印所有数据。
    1. 编写代码,实现ADC采集值(0-4095)换算为电压(0-3.3V),判断电压是否在1.0V-2.5V之间,打印换算结果和判断结论。
    1. 尝试使用变量阴影化,将一个整数变量转换为字符串变量,打印转换前后的类型(可借助std::any::type_name函数)。

六、课程总结

  • 核心知识点:变量的声明规则、可变性与阴影化;标量与复合数据类型的分类及嵌入式用途;各类运算符的用法及优先级。

  • 实操重点:规范声明变量,根据场景选择不可变/可变变量;熟练使用常用数据类型,掌握运算符在嵌入式数据处理中的应用。

  • 关键结论:Rust基础语法是后续嵌入式开发的核心,变量不可变性、强类型特性的设计,能提升嵌入式程序的安全性和稳定性。

七、课程关键词(重点记忆)

  • 变量、let、mut、变量阴影化

  • 标量类型、复合类型、数组、元组

  • 算术运算符、比较运算符、逻辑运算符

  • 嵌入式数据类型适配、Rust强类型

八、课程回顾总结

本课时作为Rust基础入门的核心内容,重点讲解了Rust基础语法中的变量、数据类型和运算符,为后续Rust嵌入式开发筑牢语法基础。课程开篇明确了变量的声明规则,强调Rust变量默认不可变的特性,这是Rust内存安全设计的重要体现,契合嵌入式开发对程序稳定性的要求,同时讲解了可变变量(mut关键字)和变量阴影化的用法,区分二者的差异,避免开发中出现语法错误。

数据类型部分,重点介绍了嵌入式开发中常用的标量类型和简单复合类型,明确了不同类型的适用场景,比如u8用于GPIO电平、f32用于传感器浮点数据、元组和数组用于组合相关数据,让学员能根据实际开发需求选择合适的数据类型。运算符部分,聚焦算术、比较、逻辑三类核心运算符,结合嵌入式数据处理场景(如ADC值换算、阈值判断)进行演示,帮助学员理解运算符的实际用途和优先级。

课程通过三个实操示例,将理论知识与实践结合,让学员直观感受Rust语法的特点,同时布置分层课后作业,巩固变量、数据类型和运算符的用法。本课时的难点的是变量阴影化的理解和复合数据类型的实操,学员需通过多练习,规范代码编写格式,规避基础语法错误。通过本课时的学习,学员已掌握Rust基础语法核心内容,具备编写简单Rust代码的能力,为后续所有权、函数等知识点的学习,以及STM32嵌入式实操奠定了坚实基础。

上节课作业答案:Rust简介与环境搭建 - 实战作业代码及说明

一、实战作业代码(可直接复制运行)

rust 复制代码
// src/main.rs
fn main() {
    // 打印作业标题
    println!("STM32 Rust第1课时作业");
    println!("======================");

    // 打印Rust工具链版本信息(验证环境)
    println!("当前Rust编译器版本:rustc 1.94.0");
    println!("当前Cargo版本:cargo 1.94.0");

    // 验证嵌入式工具链(STM32适配)
    println!("\n嵌入式工具链验证:");
    println!("适配STM32 Cortex-M3内核目标:thumbv7m-none-eabi");
    println!("已安装工具:cargo-flash、cargo-embed、probe-rs");

    // 模拟STM32开发板信息打印(贴合嵌入式场景)
    println!("\nSTM32开发板信息:");
    println!("开发板型号:STM32F103C8T6");
    println!("内核:Cortex-M3");
    println!("调试工具:ST-Link");

    // 打印作业完成提示
    println!("\n作业完成!环境搭建正常,可进入后续Rust语法学习。");
}

二、代码功能说明

本代码为第1课时实战作业核心代码,用于验证Rust工具链及STM32嵌入式适配环境是否搭建成功。代码首先打印作业标题及分隔线,清晰区分作业内容;随后打印Rust编译器和Cargo包管理器版本,直观验证基础环境安装有效性;接着验证STM32嵌入式工具链适配情况,明确标注适配的STM32内核目标及已安装的烧录、调试工具;最后模拟打印STM32开发板信息,贴合嵌入式学习场景,结尾给出作业完成提示。整体代码简洁易懂,无复杂逻辑,核心作用是验证环境,同时让学员熟悉Rust基础打印语法,为后续实操铺垫。

三、注意事项

    1. 运行代码前,需确保Rust工具链及STM32适配工具(cargo-flash、probe-rs等)已安装完成,环境变量生效。
    1. 代码运行命令为cargo run,需在创建的Rust项目(如hello_rust)的src/main.rs文件中修改代码。
    1. 若运行时提示"命令未找到",需重启终端,确保环境变量完全生效,或手动执行环境生效命令。
    1. 可根据实际安装的Rust版本,修改代码中版本号,确保打印信息与实际一致。
    1. 若连接ST-Link调试器,可在代码中添加调试日志,进一步验证调试工具是否正常识别。

Rust编程基础课 第1课时:Rust简介与环境搭建 STM32 RUST嵌入式编程实战