Rust从入门到精通之入门篇:6.函数

embedded/2025/3/29 23:44:19/

函数

在本章中,我们将学习 Rust 中的函数定义和使用。函数是 Rust 程序的基本构建块,它允许我们将代码组织成可重用的块,提高代码的可读性和可维护性。

函数定义

Rust 中使用 fn 关键字定义函数。函数名遵循 Rust 的命名约定,使用蛇形命名法(snake_case)。

rust">fn main() {println!("Hello, world!");another_function();
}fn another_function() {println!("这是另一个函数。");
}

在上面的例子中,我们定义了两个函数:mainanother_functionmain 函数是程序的入口点,another_function 是我们自定义的函数。

函数参数

函数可以接受参数,这些参数是传递给函数的值。在函数签名中,必须声明每个参数的类型。

rust">fn main() {print_number(5);print_labeled_measurement(5, 'h');
}fn print_number(x: i32) {println!("x 的值是: {}", x);
}fn print_labeled_measurement(value: i32, unit_label: char) {println!("测量值是: {}{}", value, unit_label);
}

在这个例子中,print_number 函数接受一个 i32 类型的参数,print_labeled_measurement 函数接受一个 i32 类型和一个 char 类型的参数。

函数体中的语句和表达式

Rust 是一种基于表达式的语言。语句是执行操作但不返回值的指令,而表达式则是计算并产生一个值。

rust">fn main() {let y = 6; // 语句let x = 5; // 语句// 表达式let y = {let x = 3;x + 1 // 注意这里没有分号,这是一个表达式};println!("y 的值是: {}", y); // 输出:y 的值是: 4
}

在上面的例子中,代码块 { let x = 3; x + 1 } 是一个表达式,它计算并返回一个值。注意,表达式的最后一行没有分号,因为它是要返回的值。如果在表达式的末尾添加分号,它就变成了一个语句,不会返回值。

带返回值的函数

函数可以向调用它的代码返回值。我们在箭头(->)后面声明返回值的类型,但不对返回值命名。

rust">fn five() -> i32 {5 // 返回值,注意没有分号
}fn main() {let x = five();println!("x 的值是: {}", x);
}

在 Rust 中,函数的返回值等同于函数体最后一个表达式的值。也可以使用 return 关键字提前从函数返回,但大多数函数隐式地返回最后一个表达式。

rust">fn plus_one(x: i32) -> i32 {x + 1 // 返回 x + 1 的值
}fn main() {let x = plus_one(5);println!("x 的值是: {}", x); // 输出:x 的值是: 6
}

如果在表达式后面加上分号,它就变成了语句,不会返回值:

rust">fn plus_one(x: i32) -> i32 {x + 1; // 错误:此函数的块不返回值
}

注释函数

可以使用文档注释来为函数提供文档:

rust">/// 将输入值加一并返回
///
/// # Examples
///
/// ```
/// let five = 5;
/// let six = plus_one(5);
/// assert_eq!(6, six);
/// ```
fn plus_one(x: i32) -> i32 {x + 1
}

函数重载

Rust 不支持函数重载(即同名但参数不同的多个函数)。每个函数名在其作用域内必须是唯一的。

闭包

Rust 有一种类似于函数的特性,称为闭包(closures)。闭包是可以保存在变量中或作为参数传递给其他函数的匿名函数。

rust">fn main() {let add_one = |x: i32| -> i32 { x + 1 };let five = 5;println!("{}+1={}", five, add_one(five));
}

闭包可以捕获其环境中的值:

rust">fn main() {let x = 4;let equal_to_x = |z| z == x;let y = 4;assert!(equal_to_x(y));
}

高阶函数

Rust 支持高阶函数,即接受函数作为参数或返回函数的函数。

rust">fn apply_twice<F>(f: F, x: i32) -> i32
whereF: Fn(i32) -> i32,
{f(f(x))
}fn main() {let add_one = |x| x + 1;let result = apply_twice(add_one, 5);println!("结果是: {}", result); // 输出:结果是: 7
}

示例程序

让我们编写一个程序,展示 Rust 中函数的各种用法:

rust">fn main() {// 调用无参数函数say_hello();// 调用带参数的函数greet("Alice");// 调用多参数函数let sum = add(5, 7);println!("5 + 7 = {}", sum);// 使用函数返回值let result = calculate_rectangle_area(4.5, 6.2);println!("矩形面积: {}", result);// 使用表达式作为函数体let squared = square(3);println!("3 的平方是: {}", squared);// 使用闭包let is_even = |n: i32| n % 2 == 0;for i in 1..=5 {println!("{} 是偶数: {}", i, is_even(i));}// 使用高阶函数let numbers = [1, 2, 3, 4, 5];let sum: i32 = numbers.iter().map(|&x| x * 2).sum();println!("数组中所有元素乘以 2 后的总和: {}", sum);
}// 无参数函数
fn say_hello() {println!("Hello!");
}// 带一个参数的函数
fn greet(name: &str) {println!("你好, {}!", name);
}// 带两个参数的函数
fn add(a: i32, b: i32) -> i32 {a + b // 返回 a + b 的值
}// 带两个浮点参数的函数
fn calculate_rectangle_area(width: f64, height: f64) -> f64 {width * height
}// 使用表达式作为函数体
fn square(n: i32) -> i32 {n * n
}

练习题

  1. 编写一个函数 is_palindrome,接受一个字符串参数,判断它是否是回文(正着读和倒着读一样)。

  2. 编写一个函数 fibonacci,接受一个整数 n,返回斐波那契数列的第 n 个数。

  3. 编写一个高阶函数 transform_array,接受一个整数数组和一个函数作为参数,对数组中的每个元素应用该函数,并返回结果数组。

  4. 编写一个函数 calculate_average,接受一个整数数组,返回其平均值。

  5. 编写一个闭包,用于过滤出数组中的所有偶数,并使用它来处理一个整数数组。

总结

在本章中,我们学习了:

  • 如何定义和调用函数
  • 函数参数和返回值的声明
  • 语句和表达式的区别
  • 如何使用闭包
  • 高阶函数的概念和用法

函数是 Rust 程序的基本构建块,掌握函数的定义和使用对于编写清晰、模块化的代码至关重要。在下一章中,我们将学习 Rust 中的注释和文档,这对于代码的可读性和可维护性同样重要。


http://www.ppmy.cn/embedded/176863.html

相关文章

CMS迁移中SEO优化整合步骤详解

内容概要 在CMS迁移过程中&#xff0c;系统化的规划与执行是保障SEO排名稳定性的核心。首先需明确迁移流程的关键阶段&#xff0c;包括数据备份、URL适配、元数据同步及安全配置等环节。其中&#xff0c;数据备份不仅需覆盖原始数据库与静态资源&#xff0c;还需验证备份文件的…

Docker 安装 Nginx

以下是安装并配置 Docker 版 Nginx 的步骤&#xff1a; docker仓库&#xff1a;https://hub.docker.com/_/nginx 1. 拉取指定版本的 Nginx 镜像 # 选定1.27.4版本 docker pull nginx:1.27.42. 创建本地目录结构 mkdir -p /root/docker/nginx/{conf,html,logs,ssl}3. &#x…

ROS2 部署大语言模型节点

4GB GPU的DeepSeek-Coder 1.3B模型&#xff0c;并且它已经被量化或优化过。以下是具体的步骤&#xff1a; 安装必要的依赖项&#xff1a; pip install transformers torch grpcio googleapis-common-protos创建一个新的ROS 2包&#xff1a; cd ~/ros2_ws/src ros2 pkg creat…

游戏引擎学习第174天

回顾并规划今天的任务 正在进行一些复杂的工作。之前正在处理语言相关的任务&#xff0c;不过有些人提到空格处理不当&#xff0c;这是因为字距设置的问题&#xff0c;所以应该优先修复这个问题&#xff0c;这并不是什么复杂的修复&#xff0c;应该可以快速解决。 现在有一些…

循环查询指定服务器开放端口(Python)

循环查询指定服务器开放端口列表 # Time : 2025/3/22 # Author : cookie # Desc :import socket import concurrent.futures from datetime import datetime# 设置目标IP和端口范围 target_ip input("请输入目标IP地址: ") start_port int(input("请输入…

深度学习项目--基于ResNet和DenseNet混合架构网络论文的复现(pytorch实现)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 如果说最经典的神经网络&#xff0c;ResNet当之无愧&#xff0c;后面基于ResNet网络提出DenseNet网络&#xff0c;也获得了best paper&#xff0c;本文…

设计一个基于机器学习的光伏发电功率预测模型,以Python和Scikit - learn库为例

下面为你设计一个基于机器学习的光伏发电功率预测模型&#xff0c;以Python和Scikit - learn库为例。此模型借助历史气象数据和光伏发电功率数据来预测未来的光伏发电功率。 模型设计思路 数据收集&#xff1a;收集历史气象数据&#xff08;像温度、光照强度、湿度等&#xf…

蓝桥杯第十届 数的分解

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 把 2019 分解成 3 个各不相同的正整数之和&#xff0c;并且要求每个正整数都不包含数字 2 和 4&#xff0c;一共有多少种不同的分解方法&#xff1f; 注意交换 3 个…