第7篇:功能------打造你的工具箱
作者: 李金雨
联系方式: wbtm2718@qq.com
目标读者: Rust中文编程
核心理念: AI时代必须使用中文编程,母语编程阅读效率极高
1. 开篇引入
本课目标
- 理解什么是函数
- 掌握函数的定义方法
- 掌握函数的调用方法
- 理解函数的参数和返回值
- 理解函数的嵌套调用
生活场景引入
想象一下,你有一个工具箱,里面有各种工具:
- 锤子:用来钉钉子
- 螺丝刀:用来拧螺丝
- 尺子:用来测量长度
- 计算器:用来计算
每个工具都有自己的用途,你可以根据需要使用它们。在编程中,函数就像这些工具,每个函数都有自己的功能,你可以调用它们来完成特定的任务。
预期成果展示
通过这节课的学习,你将能够:
- 定义自己的函数
- 调用函数来完成任务
- 给函数传递参数
- 接收函数的返回值
- 理解函数的嵌套调用
2. 概念讲解
什么是函数?
函数就像一个工具,它接收一些输入(参数),进行一些操作,然后返回一个输出(返回值)。
定义函数
在Rust中,我们使用fn关键字来定义函数:
rust
fn main() {
fn 函数名(参数1: 类型1, 参数2: 类型2) -> 返回类型 {
// 函数体
// 最后一行表达式的结果就是返回值
}
}
例如:
rust
fn main() {
// 定义一个加法函数
fn 加法(数字1: i32, 数字2: i32) -> i32 {
数字1 + 数字2
}
// 定义一个打印函数
fn 打印(内容: &str) {
println!("{}", 内容);
}
}
调用函数
调用函数就像使用工具一样,你需要提供必要的参数:
rust
fn main() {
// 定义一个加法函数
fn 加法(数字1: i32, 数字2: i32) -> i32 {
数字1 + 数字2
}
// 调用加法函数
let 结果 = 加法(1, 2);
println!("1 + 2 = {}", 结果);
// 定义一个打印函数
fn 打印(内容: &str) {
println!("{}", 内容);
}
// 调用打印函数
打印("你好,世界!");
}
函数参数
函数参数就像工具的原材料,你需要提供它们才能让工具工作:
rust
fn main() {
// 定义一个计算面积的函数
fn 计算面积(长: f64, 宽: f64) -> f64 {
长 * 宽
}
// 调用函数
let 面积 = 计算面积(5.0, 3.0);
println!("面积:{}", 面积);
}
函数返回值
函数返回值就像工具加工后的成品,它是函数执行的结果:
rust
fn main() {
// 定义一个计算平均值的函数
fn 计算平均值(数字们: &[i32]) -> f64 {
let mut 总和 = 0;
for 数字 in 数字们 {
总和 += 数字;
}
总和 as f64 / 数字们.len() as f64
}
// 调用函数
let 数字们 = [1, 2, 3, 4, 5];
let 平均值 = 计算平均值(&数字们);
println!("平均值:{}", 平均值);
}
函数体和表达式
函数体是函数的具体实现,它由一系列语句组成。在Rust中,函数的返回值通常是函数体的最后一个表达式:
rust
fn main() {
fn 函数名() -> 返回类型 {
// 语句1
// 语句2
// ...
// 最后一个表达式就是返回值
表达式
}
}
你也可以使用return关键字来显式返回值:
rust
fn main() {
fn 比较大小(a: i32, b: i32) -> i32 {
if a > b {
return a;
} else {
return b;
}
}
}
函数调用函数
函数可以调用其他函数,这就是函数的嵌套调用:
rust
fn main() {
// 定义一个计算平方的函数
fn 平方(数字: i32) -> i32 {
数字 * 数字
}
// 定义一个计算平方根的函数
fn 平方根(数字: f64) -> f64 {
数字.sqrt()
}
// 定义一个计算距离的函数
fn 计算距离(x1: i32, y1: i32, x2: i32, y2: i32) -> f64 {
let 差x = x2 - x1;
let 差y = y2 - y1;
let 平方和 = 平方(差x) + 平方(差y);
平方根(平方和 as f64)
}
// 调用函数
let 距离 = 计算距离(0, 0, 3, 4);
println!("距离:{}", 距离);
}
内置函数和宏
Rust提供了很多内置的函数和宏,比如println!、String::from、vec!等:
rust
fn main() {
// 使用内置函数
let 字符串 = String::from("你好");
println!("字符串长度:{}", 字符串.len());
// 使用宏
let 数字们 = vec![1, 2, 3, 4, 5];
println!("数字们:{:?}", 数字们);
}
3. 动手实践
基础练习(必做)
-
制作数学工具箱 :创建一个程序,包含求和、平均、最大最小值函数:
rust// 求和函数 fn 求和(数字们: &[i32]) -> i32 { let mut 总和 = 0; for 数字 in 数字们 { 总和 += 数字; } 总和 } // 平均函数 fn 平均(数字们: &[i32]) -> f64 { let 总和 = 求和(数字们); 总和 as f64 / 数字们.len() as f64 } // 最大值函数 fn 最大值(数字们: &[i32]) -> i32 { let mut 最大 = 数字们[0]; for &数字 in 数字们 { if 数字 > 最大 { 最大 = 数字; } } 最大 } // 最小值函数 fn 最小值(数字们: &[i32]) -> i32 { let mut 最小 = 数字们[0]; for &数字 in 数字们 { if 数字 < 最小 { 最小 = 数字; } } 最小 } fn main() { let 数字们 = [1, 2, 3, 4, 5]; println!("数字们:{:?}", 数字们); println!("总和:{}", 求和(&数字们)); println!("平均:{}", 平均(&数字们)); println!("最大值:{}", 最大值(&数字们)); println!("最小值:{}", 最小值(&数字们)); } -
制作字符串工具箱 :创建一个程序,包含统计字数、反转文字函数:
rust// 统计字数函数 fn 统计字数(文字: &str) -> usize { 文字.chars().count() } // 反转文字函数 fn 反转文字(文字: &str) -> String { 文字.chars().rev().collect() } fn main() { let 文字 = "Hello, World!"; println!("原文字:{}", 文字); println!("字数:{}", 统计字数(文字)); println!("反转后:{}", 反转文字(文字)); } -
制作单位转换器 :创建一个程序,包含长度、重量、温度转换函数:
rust// 长度转换:公里转英里 fn 公里转英里(公里: f64) -> f64 { 公里 * 0.621371 } // 重量转换:公斤转磅 fn 公斤转磅(公斤: f64) -> f64 { 公斤 * 2.20462 } // 温度转换:摄氏度转华氏度 fn 摄氏度转华氏度(摄氏度: f64) -> f64 { 摄氏度 * 9.0 / 5.0 + 32.0 } fn main() { let 公里 = 10.0; println!("{}公里 = {}英里", 公里, 公里转英里(公里)); let 公斤 = 50.0; println!("{}公斤 = {}磅", 公斤, 公斤转磅(公斤)); let 摄氏度 = 25.0; println!("{}摄氏度 = {}华氏度", 摄氏度, 摄氏度转华氏度(摄氏度)); }
进阶练习(选做)
-
制作数学计算器 :创建一个程序,包含加减乘除函数:
rustfn 加法(a: f64, b: f64) -> f64 { a + b } fn 减法(a: f64, b: f64) -> f64 { a - b } fn 乘法(a: f64, b: f64) -> f64 { a * b } fn 除法(a: f64, b: f64) -> f64 { a / b } fn main() { let a = 10.0; let b = 5.0; println!("{} + {} = {}", a, b, 加法(a, b)); println!("{} - {} = {}", a, b, 减法(a, b)); println!("{} * {} = {}", a, b, 乘法(a, b)); println!("{} / {} = {}", a, b, 除法(a, b)); } -
制作判断函数 :创建一个程序,包含判断是否为偶数、是否为素数函数:
rust// 判断是否为偶数 fn 是偶数(数字: i32) -> bool { 数字 % 2 == 0 } // 判断是否为素数 fn 是素数(数字: i32) -> bool { if 数字 <= 1 { return false; } for 除数 in 2..数字 { if 数字 % 除数 == 0 { return false; } } true } fn main() { let 数字 = 17; println!("{}是否为偶数:{}", 数字, 是偶数(数字)); println!("{}是否为素数:{}", 数字, 是素数(数字)); }
挑战练习(拓展)
-
制作综合性工具 :创建一个程序,包含多个功能函数:
rust// 计算阶乘 fn 阶乘(数字: u32) -> u64 { if 数字 == 0 || 数字 == 1 { 1 } else { 数字 as u64 * 阶乘(数字 - 1) } } // 计算斐波那契数列 fn 斐波那契(数字: u32) -> u64 { if 数字 == 0 { 0 } else if 数字 == 1 { 1 } else { 斐波那契(数字 - 1) + 斐波那契(数字 - 2) } } // 生成随机数(简单版本) fn 随机数(最大值: i32) -> i32 { use std::time::SystemTime; let 时间 = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as i32; 时间 % (最大值 + 1) } fn main() { println!("5的阶乘:{}", 阶乘(5)); println!("斐波那契数列第10项:{}", 斐波那契(10)); println!("0-99的随机数:{}", 随机数(99)); }
4. 知识总结
核心概念回顾
- 函数:完成特定任务的代码块
- 参数:传递给函数的输入值
- 返回值:函数执行后返回的结果
- 函数定义 :使用
fn关键字定义函数 - 函数调用:通过函数名和参数调用函数
- 函数体:函数的具体实现
- 表达式:函数体中的代码,最后一个表达式是返回值
- 嵌套调用:函数可以调用其他函数
关键代码速查
| 功能 | 代码 | 说明 |
|---|---|---|
| 函数定义 | fn 函数名(参数: 类型) -> 返回类型 { 代码 } |
定义一个函数 |
| 函数调用 | 函数名(参数) |
调用一个函数 |
| 无返回值 | fn 函数名() {} |
函数没有返回值 |
| 显式返回 | return 值; |
显式返回一个值 |
| 表达式返回 | 值 |
函数体最后一个表达式作为返回值 |
常见错误提醒
- 参数类型不匹配:调用函数时提供的参数类型与函数定义不匹配
- 返回类型不匹配:函数返回的值类型与函数定义的返回类型不匹配
- 参数数量不匹配:调用函数时提供的参数数量与函数定义不匹配
- 函数未定义:调用了未定义的函数
5. 课后作业
巩固练习题
- 编写一个函数,计算两个数的最大公约数
- 编写一个函数,将字符串转换为大写
- 编写一个函数,计算三角形的面积(根据三边长度)
创意编程题
- 发挥你的创意,创建一个程序,包含多个功能函数,比如计算BMI指数、判断闰年等
- 编写一个程序,实现一个简单的密码生成器函数
下篇预习提示
下一篇我们将学习"结构模板------自定义数据类型",就像学习如何创建自己的模板来组织数据。预习一下:
- 什么是结构体?
- 如何定义结构体?
- 如何创建结构体实例?
- 如何访问和修改结构体字段?
恭喜你完成了第七篇教程!你已经掌握了函数的定义和使用,学会了如何打造自己的工具箱。继续加油,下一篇我们将学习如何创建自定义数据类型!
学习交流
如果你在学习过程中遇到任何问题,欢迎联系我:
- ** 视频号,"时空系"
- 邮箱: wbtm2718@qq.com
- 其他提示:
- 本人正在开发纯中文编程语言和编译器,有兴趣的可以交流
- 本人正在写一本基于中国母语思维习惯的数学教材,可以让你一年内学完从初中到研究生的数学,而且可以让你快速掌握人工智能的关键数学知识,有兴趣的可以交流
祝你学习愉快!