第8篇:结构模板------自定义数据类型
作者: 李金雨
联系方式: wbtm2718@qq.com
目标读者: Rust中文编程
核心理念: AI时代必须使用中文编程,母语编程阅读效率极高
1. 开篇引入
本课目标
- 理解什么是结构模板(结构体)
- 掌握结构体的定义方法
- 掌握创建结构体实例的方法
- 掌握访问和修改结构体字段的方法
- 理解结构体的用途
生活场景引入
想象一下,你需要填写一份学生登记表,上面有姓名、年龄、性别、班级、成绩等信息。这份登记表就是一个模板,你可以用它来记录每个学生的信息。
在编程中,结构体就像这样的模板,它定义了一组相关的数据字段,你可以用它来创建具体的实例。
预期成果展示
通过这节课的学习,你将能够:
- 定义自己的结构体
- 创建结构体实例
- 访问和修改结构体字段
- 理解结构体在组织数据方面的优势
2. 概念讲解
什么是结构模板(结构体)
结构体是一种自定义的数据类型,它可以包含多个不同类型的字段。就像一个表单,包含多个输入项。
例如,我们可以定义一个学生结构体,包含姓名、年龄、成绩等字段:
rust
fn main() {
struct 学生 {
姓名: String,
年龄: i32,
成绩: i32,
科目列表: Vec<String>,
}
}
为什么要用结构体
- 组织相关数据:将相关的数据放在一起,使代码更清晰
- 代码复用:可以创建多个相同类型的实例
- 数据封装:可以将数据和操作数据的方法放在一起
- 类型安全:编译器会检查结构体的字段类型
定义结构体
在Rust中,我们使用struct关键字来定义结构体:
rust
struct 结构体名 {
字段1: 类型1,
字段2: 类型2,
// 更多字段...
}
例如:
rust
fn main() {
// 定义一个学生结构体
struct 学生 {
姓名: String,
年龄: i32,
成绩: i32,
科目列表: Vec<String>,
}
// 定义一个汽车结构体
struct 汽车 {
品牌: String,
型号: String,
颜色: String,
速度: f64,
}
// 定义一个书籍结构体
struct 书籍 {
书名: String,
作者: String,
价格: f64,
页数: i32,
}
}
创建实例
创建结构体实例就像填写表单一样,需要为每个字段提供值:
rust
fn main() {
struct 学生 {
姓名: String,
年龄: i32,
成绩: i32,
科目列表: Vec<String>,
}
struct 汽车 {
品牌: String,
型号: String,
颜色: String,
速度: f64,
}
struct 书籍 {
书名: String,
作者: String,
价格: f64,
页数: i32,
}
// 创建学生实例
let 学生一 = 学生 {
姓名: String::from("张三"),
年龄: 15,
成绩: 95,
科目列表: vec![String::from("数学"), String::from("英语")],
};
// 创建汽车实例
let 汽车一 = 汽车 {
品牌: String::from("丰田"),
型号: String::from("卡罗拉"),
颜色: String::from("白色"),
速度: 0.0,
};
// 创建书籍实例
let 书籍一 = 书籍 {
书名: String::from("Rust编程入门"),
作者: String::from("李金雨"),
价格: 49.9,
页数: 300,
};
}
如果已经有一个实例,你可以基于它创建新的实例,只修改部分字段:
rust
fn main() {
struct 学生 {
姓名: String,
年龄: i32,
成绩: i32,
科目列表: Vec<String>,
}
let 学生一 = 学生 {
姓名: String::from("张三"),
年龄: 15,
成绩: 95,
科目列表: vec![String::from("数学")],
};
let 学生二 = 学生 {
姓名: String::from("李四"),
..学生一 // 使用学生一的其他字段值
};
}
访问和修改字段
访问结构体字段使用点号(.):
rust
fn main() {
struct 学生 {
姓名: String,
年龄: i32,
成绩: i32,
科目列表: Vec<String>,
}
let 学生一 = 学生 {
姓名: String::from("张三"),
年龄: 15,
成绩: 95,
科目列表: vec![],
};
// 访问字段
println!("姓名:{}", 学生一.姓名);
println!("年龄:{}岁", 学生一.年龄);
println!("成绩:{}分", 学生一.成绩);
}
修改结构体字段需要使用mut关键字:
rust
fn main() {
struct 学生 {
姓名: String,
年龄: i32,
成绩: i32,
科目列表: Vec<String>,
}
let mut 学生一 = 学生 {
姓名: String::from("张三"),
年龄: 15,
成绩: 95,
科目列表: vec![],
};
// 修改字段
学生一.成绩 = 98;
学生一.科目列表.push(String::from("数学"));
println!("修改后的成绩:{}分", 学生一.成绩);
println!("科目列表:{:?}", 学生一.科目列表);
}
3. 动手实践
基础练习(必做)
-
创建"动物"结构体 :创建一个程序,定义动物结构体并创建实例:
ruststruct 动物 { 名称: String, 年龄: i32, 声音: String, } fn main() { let 猫 = 动物 { 名称: String::from("猫咪"), 年龄: 2, 声音: String::from("喵喵"), }; let 狗 = 动物 { 名称: String::from("狗狗"), 年龄: 3, 声音: String::from("汪汪"), }; println!("{}今年{}岁,叫声是{}", 猫.名称, 猫.年龄, 猫.声音); println!("{}今年{}岁,叫声是{}", 狗.名称, 狗.年龄, 狗.声音); } -
创建"汽车"结构体 :创建一个程序,定义汽车结构体并修改字段:
ruststruct 汽车 { 品牌: String, 颜色: String, 速度: f64, } fn main() { let mut 我的汽车 = 汽车 { 品牌: String::from("大众"), 颜色: String::from("黑色"), 速度: 0.0, }; println!("我的汽车是{}牌,颜色是{},当前速度是{}km/h", 我的汽车.品牌, 我的汽车.颜色, 我的汽车.速度); // 加速 我的汽车.速度 = 60.0; println!("加速后,速度是{}km/h", 我的汽车.速度); // 减速 我的汽车.速度 = 30.0; println!("减速后,速度是{}km/h", 我的汽车.速度); } -
创建"书籍"结构体 :创建一个程序,定义书籍结构体并基于现有实例创建新实例:
ruststruct 书籍 { 书名: String, 作者: String, 价格: f64, 页数: i32, } fn main() { let 书籍一 = 书籍 { 书名: String::from("Rust编程入门"), 作者: String::from("李金雨"), 价格: 49.9, 页数: 300, }; // 基于书籍一创建书籍二 let 书籍二 = 书籍 { 书名: String::from("Rust高级编程"), 价格: 59.9, ..书籍一 }; println!("书籍一:{},作者:{},价格:{}元,页数:{}页", 书籍一.书名, 书籍一.作者, 书籍一.价格, 书籍一.页数); println!("书籍二:{},作者:{},价格:{}元,页数:{}页", 书籍二.书名, 书籍二.作者, 书籍二.价格, 书籍二.页数); }
进阶练习(选做)
-
创建"点"结构体 :创建一个程序,定义点结构体并计算两点之间的距离:
ruststruct 点 { x: f64, y: f64, } fn 计算距离(点一: &点, 点二: &点) -> f64 { let 差x = 点二.x - 点一.x; let 差y = 点二.y - 点一.y; (差x * 差x + 差y * 差y).sqrt() } fn main() { let 点一 = 点 { x: 0.0, y: 0.0 }; let 点二 = 点 { x: 3.0, y: 4.0 }; let 距离 = 计算距离(&点一, &点二); println!("点({}, {})和点({}, {})之间的距离是{}", 点一.x, 点一.y, 点二.x, 点二.y, 距离); } -
创建"矩形"结构体 :创建一个程序,定义矩形结构体并计算面积和周长:
ruststruct 矩形 { 长: f64, 宽: f64, } fn 计算面积(矩形: &矩形) -> f64 { 矩形.长 * 矩形.宽 } fn 计算周长(矩形: &矩形) -> f64 { 2.0 * (矩形.长 + 矩形.宽) } fn main() { let 我的矩形 = 矩形 { 长: 5.0, 宽: 3.0 }; println!("矩形的长:{},宽:{}", 我的矩形.长, 我的矩形.宽); println!("面积:{}", 计算面积(&我的矩形)); println!("周长:{}", 计算周长(&我的矩形)); }
挑战练习(拓展)
-
创建"学生管理系统" :创建一个程序,使用向量存储学生结构体实例:
ruststruct 学生 { 姓名: String, 年龄: i32, 成绩: i32, } fn main() { let mut 学生们 = vec![ 学生 { 姓名: String::from("张三"), 年龄: 15, 成绩: 95 }, 学生 { 姓名: String::from("李四"), 年龄: 14, 成绩: 88 }, 学生 { 姓名: String::from("王五"), 年龄: 15, 成绩: 92 }, ]; // 添加新学生 学生们.push(学生 { 姓名: String::from("赵六"), 年龄: 14, 成绩: 85 }); // 打印所有学生信息 println!("学生信息:"); for (索引, 学生) in 学生们.iter().enumerate() { println!("第{}名:姓名:{},年龄:{}岁,成绩:{}分", 索引 + 1, 学生.姓名, 学生.年龄, 学生.成绩); } // 计算平均成绩 let mut 总分 = 0; for 学生 in &学生们 { 总分 += 学生.成绩; } let 平均分 = 总分 as f64 / 学生们.len() as f64; println!("平均成绩:{}分", 平均分); }
4. 知识总结
核心概念回顾
- 结构体:自定义的数据类型,包含多个字段
- 字段:结构体中的数据成员,每个字段有自己的类型
- 实例:根据结构体模板创建的具体对象
- 访问字段:使用点号(.)访问结构体实例的字段
- 修改字段 :需要使用
mut关键字使结构体实例可变 - 结构体更新语法:基于现有实例创建新实例,只修改部分字段
关键代码速查
| 功能 | 代码 | 说明 |
|---|---|---|
| 结构体定义 | struct 结构体名 { 字段: 类型, ... } |
定义一个结构体 |
| 创建实例 | let 实例 = 结构体名 { 字段: 值, ... }; |
创建结构体实例 |
| 访问字段 | 实例.字段 |
访问结构体字段 |
| 修改字段 | 实例.字段 = 值; |
修改结构体字段(需要mut) |
| 结构体更新 | let 新实例 = 结构体名 { 字段: 新值, ..旧实例 }; |
基于现有实例创建新实例 |
常见错误提醒
- 字段初始化:创建实例时必须为所有字段提供值
- 字段访问:不能访问不存在的字段
- 可变实例 :修改字段时需要使用
mut关键字 - 所有权:结构体中的字段遵循Rust的所有权规则
5. 课后作业
巩固练习题
- 编写一个程序,定义"手机"结构体,包含品牌、型号、价格、颜色等字段
- 编写一个程序,定义"学校"结构体,包含名称、地址、学生人数等字段
- 编写一个程序,定义"电影"结构体,包含片名、导演、评分、上映年份等字段
创意编程题
- 发挥你的创意,创建一个程序,定义"游戏角色"结构体,包含姓名、等级、生命值、魔法值等字段
- 编写一个程序,定义"银行账户"结构体,包含账号、姓名、余额等字段,并实现存款、取款功能
下篇预习提示
下一篇我们将学习"成员功能------为结构体添加能力",就像学习如何为结构体添加方法,使它们具有更多的功能。预习一下:
- 什么是方法?
- 如何为结构体实现方法?
- 方法与函数有什么区别?
- 什么是关联函数?
恭喜你完成了第八篇教程!你已经掌握了结构体的定义和使用,学会了如何创建自定义数据类型。继续加油,下一篇我们将学习如何为结构体添加方法!
学习交流
如果你在学习过程中遇到任何问题,欢迎联系我:
- ** 视频号,"时空系"
- 邮箱: wbtm2718@qq.com
- 其他提示:
- 本人正在开发纯中文编程语言和编译器,有兴趣的可以交流
- 本人正在写一本基于中国母语思维习惯的数学教材,可以让你一年内学完从初中到研究生的数学,而且可以让你快速掌握人工智能的关键数学知识,有兴趣的可以交流
祝你学习愉快!