青少年编程与数学 02-019 Rust 编程基础 10课题、函数、闭包和迭代器
青少年编程与数学 02-019 Rust 编程基础 10课题、函数、闭包和迭代器
- 一、函数
- 1. 函数的基本定义
- 基本语法
- 示例
- 2. 函数的返回值
- 返回值示例
- 不返回值的函数
- 3. 参数传递
- 值传递示例
- 引用传递示例
- 可变引用传递示例
- 4. 函数的高级特性
- 4.1 泛型函数
- 示例
- 4.2 高阶函数
- 示例
- 5. 函数的调用约定
- 默认调用约定
- 外部调用约定
- 6. 小结
- 二、闭包
- 1. 闭包的基本概念
- 基本语法
- 示例
- 2. 闭包的类型
- 2.1 `FnOnce`
- 示例
- 2.2 `FnMut`
- 示例
- 2.3 `Fn`
- 示例
- 3. 闭包的捕获方式
- 示例
- 4. 闭包的使用场景
- 4.1 作为函数参数
- 示例
- 4.2 作为函数返回值
- 示例
- 4.3 实现函数式编程风格
- 示例
- 5. 闭包的性能
- 示例
- 6. 小结
- 三、迭代器
- 1. 迭代器的基本概念
- 示例
- 2. 创建迭代器
- 示例
- 3. 迭代器的惰性求值
- 示例
- 4. 迭代器适配器
- 常见的迭代器适配器
- 示例
- 5. 迭代器的链式操作
- 示例
- 6. 迭代器的性能
- 示例
- 7. 自定义迭代器
- 示例
- 8. 小结
- 四、综合示例
- 代码说明
- 输出结果
- 代码的正确性
- 总结
课题摘要:
在 Rust 中,函数是程序的基本构建块,用于封装可重用的代码逻辑。闭包(Closure)是一种特殊的匿名函数,它可以捕获和存储其定义环境中的变量。迭代器(Iterator)是一种用于遍历集合(如数组、向量、哈希表等)的抽象接口。
关键词:函数、闭包、迭代器
一、函数
在 Rust 中,函数是程序的基本构建块,用于封装可重用的代码逻辑。函数可以接受参数、执行操作并返回值。Rust 的函数设计既灵活又安全,支持多种参数类型、返回值类型以及高级特性(如闭包和泛型)。以下是对 Rust 中函数的详细解析。
1. 函数的基本定义
在 Rust 中,函数使用 fn
关键字定义,后面跟函数名、参数列表和返回值类型(可选)。函数体用大括号 {}
包裹。
基本语法
fn 函数名(参数列表) -> 返回类型 {// 函数体
}
- 函数名:标识函数的名称。
- 参数列表:函数的输入参数,可以有多个参数,用逗号分隔。每个参数需要指定类型。
- 返回类型:函数返回值的类型,用
->
指定。如果函数没有返回值,则可以省略-> 返回类型
。 - 函数体:函数的具体实现逻辑。
示例
以下是一个简单的函数,用于计算两个整数的和:
fn add(a: i32, b: i32) -> i32 {a + b
}fn main() {let result = add(3, 5);println!("The result is {}", result); // 输出:The result is 8
}
在这个例子中:
add
是函数名。a: i32, b: i32
是参数列表,指定了两个整数参数。-> i32
表示函数返回一个i32
类型的值。- 函数体中直接返回了
a + b
的结果。
2. 函数的返回值
Rust 中的函数可以返回值,也可以不返回值。如果函数没有返回值,则其返回类型为 ()
,即空元组类型。
返回值示例
fn main() {let result = add(3, 5);println!("The result is {}", result); // 输出:The result is 8let message = greet("Kimi");println!("{}", message); // 输出:Hello, Kimi!
}fn add(a: i32, b: i32) -> i32 {a + b
}fn greet(name: &str) -> String {format!("Hello, {}!", name)
}
不返回值的函数
如果函数没有返回值,可以省略 -> 返回类型
:
fn print_sum(a: i32, b: i32) {println!("The sum is {}", a + b);
}fn main() {print_sum(3, 5); // 输出:The sum is 8
}
3. 参数传递
Rust 中的参数传递有以下几种方式:
- 值传递:将参数的值传递给函数,函数内部对参数的修改不会影响外部变量。
- 引用传递:将参数的引用传递给函数,函数内部可以通过引用修改外部变量。
- 可变引用传递:将可变引用传递给函数,允许函数内部修改外部变量。
值传递示例
fn main() {let a = 5;let b = 3;let result = add(a, b);println!("The result is {}", result); // 输出:The result is 8println!("a = {}, b = {}", a, b); // 输出:a = 5, b = 3
}fn add(mut x: i32, y: i32) -> i32 {x += y; // 修改 x 的值x
}
在这个例子中,a
和 b
的值被传递给 add
函数,函数内部对 x
的修改不影响外部的 a
。
引用传递示例
fn main() {let a = 5;print_value(&a); // 输出:The value is 5
}fn print_value(value: &i32) {println!("The value is {}", value);
}
在这个例子中,a
的引用被传递给 print_value
函数,函数内部通过引用访问 a
的值。
可变引用传递示例
fn main() {let mut a = 5;increment(&mut a); // 修改 a 的值println!("a = {}", a); // 输出:a = 6
}fn increment(value: &mut i32) {*value += 1; // 通过可变引用修改外部变量
}
在这个例子中,a
的可变引用被传递给 increment
函数,函数内部通过解引用 *value
修改了外部变量 a
的值。
4. 函数的高级特性
4.1 泛型函数
Rust 支持泛型函数,允许函数在定义时不指定具体的类型,而是在调用时根据参数类型推断。
示例
fn main() {let a = 5;let b = 3.14;println!("The maximum is {}", max(a, b)); // 输出:The maximum is 5
}fn max<T: PartialOrd + Copy>(a: T, b: T) -> T {if a > b {a} else {b}
}
在这个例子中:
max
是一个泛型函数,T
是一个类型参数。T: PartialOrd + Copy
是类型约束,表示T
必须实现PartialOrd
和Copy
特性。- 函数内部通过
if a > b
比较两个值,并返回较大的值。
4.2 高阶函数
高阶函数是接受函数或闭包作为参数的函数。Rust 中的高阶函数可以用于实现函数式编程风格。
示例
fn main() {let numbers = vec![1, 2, 3, 4, 5];let sum = numbers.iter().fold(0, |acc, x| acc + x); // 使用 fold 函数println!("The sum is {}", sum); // 输出:The sum is 15
}
在这个例子中,fold
是一个高阶函数,它接受一个初始值和一个闭包,用于对迭代器中的元素进行累加。
5. 函数的调用约定
Rust 支持多种函数调用约定,包括默认的调用约定和外部调用约定(如 C 调用约定)。
默认调用约定
Rust 的默认调用约定是 Rust
,适用于 Rust 内部的函数调用。
外部调用约定
如果需要与其他语言(如 C)交互,可以使用外部调用约定。例如:
extern "C" fn add(a: i32, b: i32) -> i32 {a + b
}
在这个例子中,extern "C"
表示使用 C 的调用约定。
6. 小结
Rust 中的函数是程序的核心组件,具有以下特点:
- 灵活性:支持多种参数类型、返回值类型和高级特性(如泛型、闭包和高阶函数)。
- 安全性:通过所有权和借用规则,确保函数调用的安全性。
- 可重用性:函数可以封装逻辑,便于代码复用。
通过合理使用函数,可以提高代码的可读性、可维护性和可扩展性。
二、闭包
在 Rust 中,闭包(Closure)是一种特殊的匿名函数,它可以捕获和存储其定义环境中的变量。闭包在 Rust 中非常灵活且强大,常用于函数式编程风格,尤其是在需要将函数作为参数传递或返回函数时。以下是对 Rust 中闭包的详细解析。
1. 闭包的基本概念
闭包是一种可以捕获其定义环境中的变量的匿名函数。它可以在定义时捕获外部变量,并在后续调用中使用这些变量。
基本语法
闭包的语法如下:
|参数列表| -> 返回类型 { 代码块 }
- 参数列表:闭包的输入参数,用竖线
|
包裹。 - 返回类型:可选,如果闭包有返回值,可以用
->
指定返回类型。 - 代码块:闭包的主体,用大括号
{}
包裹。
示例
以下是一个简单的闭包示例,用于计算两个整数的和:
fn main() {let add = |a: i32, b: i32| -> i32 { a + b }; // 定义闭包let result = add(3, 5);println!("The result is {}", result); // 输出:The result is 8
}
在这个例子中:
|a: i32, b: i32| -> i32 { a + b }
是一个闭包,它接受两个整数参数并返回它们的和。- 闭包被赋值给变量
add
,并通过变量调用。
2. 闭包的类型
Rust 中的闭包根据其捕获环境变量的方式分为三种类型:
- FnOnce:闭包可以被调用一次,因为它可能需要获取捕获的变量的所有权。
- FnMut:闭包可以被多次调用,但每次调用可能需要修改捕获的变量。
- Fn:闭包可以被多次调用,且不会修改捕获的变量。
2.1 FnOnce
FnOnce
是最基本的闭包类型,它表示闭包可以被调用一次。如果闭包获取了捕获变量的所有权,则该闭包属于 FnOnce
类型。
示例
fn main() {let name = String::from("Kimi");let print_name = || {println!("The name is {}", name);};print_name(); // 输出:The name is Kimi// print_name(); // 错误:`print_name` 被移动了,无法再次调用
}
在这个例子中,闭包 print_name
捕获了变量 name
的所有权,因此它属于 FnOnce
类型。调用一次后,闭包被移动,无法再次调用。
2.2 FnMut
FnMut
表示闭包可以被多次调用,但每次调用可能需要修改捕获的变量。如果闭包捕获了变量的可变引用,则该闭包属于 FnMut
类型。
示例
fn main() {let mut counter = 0;let mut increment = || {counter += 1;println!("The counter is {}", counter);};increment(); // 输出:The counter is 1increment(); // 输出:The counter is 2
}
在这个例子中,闭包 increment
捕获了变量 counter
的可变引用,因此它属于 FnMut
类型。每次调用闭包时,counter
的值都会被修改。
2.3 Fn
Fn
表示闭包可以被多次调用,且不会修改捕获的变量。如果闭包捕获了变量的不可变引用,则该闭包属于 Fn
类型。
示例
fn main() {let name = String::from("Kimi");let print_name = || {println!("The name is {}", name);};print_name(); // 输出:The name is Kimiprint_name(); // 输出:The name is Kimi
}
在这个例子中,闭包 print_name
捕获了变量 name
的不可变引用,因此它属于 Fn
类型。可以多次调用闭包,而不会修改捕获的变量。
3. 闭包的捕获方式
闭包捕获环境变量的方式取决于变量的使用方式:
- 如果闭包需要修改捕获的变量,则捕获变量的可变引用。
- 如果闭包需要多次使用捕获的变量,则捕获变量的不可变引用。
- 如果闭包只需要使用一次捕获的变量,则捕获变量的所有权。
示例
fn main() {let mut count = 0;{let mut increment = || {count += 1;};increment();}println!("The count is {}", count); // 输出:The count is 1
}
在这个例子中,闭包 increment
捕获了变量 count
的可变引用,因此可以修改 count
的值。
4. 闭包的使用场景
闭包在 Rust 中非常灵活,常用于以下场景:
- 作为函数参数:将闭包传递给函数,实现回调、迭代器操作等。
- 作为函数返回值:从函数中返回闭包,实现延迟计算或封装逻辑。
- 实现函数式编程风格:使用闭包实现
map
、filter
、fold
等高阶函数。
4.1 作为函数参数
闭包常用于函数式编程中的高阶函数。例如,map
和 filter
函数接受闭包作为参数,对集合中的元素进行操作。
示例
fn main() {let numbers = vec![1, 2, 3, 4, 5];let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();println!("Doubled numbers: {:?}", doubled); // 输出:Doubled numbers: [2, 4, 6, 8, 10]let even: Vec<i32> = numbers.into_iter().filter(|x| x % 2 == 0).collect();println!("Even numbers: {:?}", even); // 输出:Even numbers: [2, 4]
}
在这个例子中:
map(|x| x * 2)
使用闭包对每个元素进行加倍操作。filter(|x| x % 2 == 0)
使用闭包过滤出偶数。
4.2 作为函数返回值
闭包可以作为函数的返回值,实现延迟计算或封装逻辑。
示例
fn main() {let add = create_adder(5);println!("The result is {}", add(3)); // 输出:The result is 8
}fn create_adder(base: i32) -> impl Fn(i32) -> i32 {move |x| x + base
}
在这个例子中:
create_adder
函数返回一个闭包,该闭包捕获了参数base
的所有权。- 返回的闭包可以被调用,实现延迟计算。
4.3 实现函数式编程风格
闭包是实现函数式编程风格的关键工具。例如,使用闭包可以实现 fold
函数,对集合中的元素进行累加。
示例
fn main() {let numbers = vec![1, 2, 3, 4, 5];let sum = numbers.iter().fold(0, |acc, x| acc + x);println!("The sum is {}", sum); // 输出:The sum is 15
}
在这个例子中,fold
函数接受一个初始值和一个闭包,对集合中的元素进行累加。
5. 闭包的性能
闭包在 Rust 中是高效的,因为它们可以捕获环境变量,避免了不必要的数据传递。闭包的性能通常与普通函数相当,但在某些情况下,闭包可以更灵活地优化性能。
示例
fn main() {let mut numbers = vec![1, 2, 3, 4, 5];numbers.sort_by(|a, b| b.cmp(a)); // 使用闭包进行排序println!("Sorted numbers: {:?}", numbers); // 输出:Sorted numbers: [5, 4, 3, 2, 1]
}
在这个例子中,sort_by
函数接受一个闭包,用于定义排序的规则。闭包的使用使得代码更加简洁和高效。
6. 小结
闭包是 Rust 中一种非常强大和灵活的工具,具有以下特点:
- 匿名函数:闭包没有名称,可以直接定义和使用。
- 捕获环境变量:闭包可以捕获其定义环境中的变量,并在后续调用中使用这些变量。
- 多种类型:闭包根据捕获变量的方式分为
FnOnce
、FnMut
和Fn
三种类型。 - 高效和灵活:闭包可以用于实现函数式编程风格,优化代码的可读性和性能。
通过合理使用闭包,可以实现复杂的逻辑控制,同时保持代码的简洁和高效。
三、迭代器
在 Rust 中,迭代器(Iterator)是一种用于遍历集合(如数组、向量、哈希表等)的抽象接口。迭代器提供了一种统一的方式来逐个访问集合中的元素,而无需暴露集合的内部表示。Rust 的迭代器设计非常灵活且功能强大,支持惰性求值、链式操作和多种迭代器适配器,使得数据处理更加高效和简洁。
1. 迭代器的基本概念
迭代器是一种可以逐个访问集合中元素的接口。在 Rust 中,迭代器通常实现了 Iterator
特性(trait),该特性定义了两个主要方法:
next()
:返回集合中的下一个元素,如果集合中没有更多元素,则返回None
。size_hint()
:返回一个元组(lower_bound, upper_bound)
,表示迭代器可能返回的元素数量的范围。
示例
以下是一个简单的迭代器示例,用于遍历一个向量中的元素:
fn main() {let vec = vec![1, 2, 3, 4, 5];let mut iter = vec.into_iter(); // 创建迭代器while let Some(value) = iter.next() { // 使用 next() 方法逐个访问元素println!("{}", value);}
}
在这个例子中:
vec.into_iter()
创建了一个迭代器,用于遍历向量vec
中的元素。iter.next()
返回集合中的下一个元素,如果集合中没有更多元素,则返回None
。- 使用
while let
语法逐个访问元素,直到迭代器耗尽。
2. 创建迭代器
Rust 提供了多种方式来创建迭代器:
- 使用
iter()
方法:创建一个不可变引用迭代器,不会获取集合的所有权。 - 使用
into_iter()
方法:创建一个获取集合所有权的迭代器。 - 使用
iter_mut()
方法:创建一个可变引用迭代器,允许修改集合中的元素。
示例
fn main() {let vec = vec![1, 2, 3, 4, 5];// 创建不可变引用迭代器let iter = vec.iter();for value in iter {println!("{}", value);}// 创建获取所有权的迭代器let vec2 = vec![1, 2, 3, 4, 5];let into_iter = vec2.into_iter();for value in into_iter {println!("{}", value);}// 创建可变引用迭代器let mut vec3 = vec![1, 2, 3, 4, 5];let mut iter_mut = vec3.iter_mut();for value in iter_mut {*value += 1; // 修改元素}println!("{:?}", vec3); // 输出:[2, 3, 4, 5, 6]
}
3. 迭代器的惰性求值
Rust 的迭代器是惰性求值的,这意味着迭代器的元素只有在需要时才会被计算。这种特性使得迭代器可以高效地处理大型集合,甚至可以处理无限序列。
示例
以下是一个无限序列的示例:
fn main() {let numbers = 0..; // 创建一个无限序列let mut iter = numbers.skip(10).take(5); // 跳过前 10 个元素,取接下来的 5 个元素while let Some(value) = iter.next() {println!("{}", value); // 输出:10, 11, 12, 13, 14}
}
在这个例子中:
0..
创建了一个无限序列。skip(10)
跳过前 10 个元素。take(5)
取接下来的 5 个元素。iter.next()
按需计算并返回元素。
4. 迭代器适配器
Rust 提供了许多迭代器适配器(Iterator Adapters),用于对迭代器进行转换和组合。这些适配器可以实现复杂的操作,而无需手动编写循环。
常见的迭代器适配器
map
:对迭代器中的每个元素应用一个函数。filter
:根据条件过滤迭代器中的元素。fold
:对迭代器中的元素进行累加或其他累积操作。collect
:将迭代器中的元素收集到一个集合中。filter_map
:结合filter
和map
的功能。flat_map
:对迭代器中的每个元素应用一个函数,该函数返回一个迭代器,然后将所有迭代器的元素展平。enumerate
:为迭代器中的每个元素添加索引。zip
:将两个迭代器组合成一个迭代器。
示例
以下是一个使用多种迭代器适配器的示例:
fn main() {let numbers = vec![1, 2, 3, 4, 5];// 使用 map 和 filterlet result: Vec<i32> = numbers.iter().map(|x| x * 2) // 对每个元素乘以 2.filter(|x| x % 3 != 0) // 过滤掉能被 3 整除的元素.collect(); // 收集到一个向量中println!("{:?}", result); // 输出:[2, 4, 8, 10]// 使用 fold 计算累加和let sum = numbers.iter().fold(0, |acc, x| acc + x);println!("The sum is {}", sum); // 输出:The sum is 15// 使用 enumerate 添加索引for (index, value) in numbers.iter().enumerate() {println!("Element at index {}: {}", index, value);}// 使用 zip 组合两个迭代器let vec1 = vec![1, 2, 3];let vec2 = vec!['a', 'b', 'c'];for (num, ch) in vec1.iter().zip(vec2.iter()) {println!("Number: {}, Character: {}", num, ch);}
}
5. 迭代器的链式操作
由于迭代器是惰性求值的,多个迭代器适配器可以链式调用,从而实现复杂的操作。链式操作不仅代码简洁,而且性能高效,因为中间结果不会被显式存储。
示例
以下是一个链式操作的示例:
fn main() {let numbers = vec![1, 2, 3, 4, 5];// 链式操作:map -> filter -> collectlet result: Vec<i32> = numbers.iter().map(|x| x * 2) // 对每个元素乘以 2.filter(|x| x % 3 != 0) // 过滤掉能被 3 整除的元素.collect(); // 收集到一个向量中println!("{:?}", result); // 输出:[2, 4, 8, 10]
}
在这个例子中:
map(|x| x * 2)
对每个元素乘以 2。filter(|x| x % 3 != 0)
过滤掉能被 3 整除的元素。collect()
将结果收集到一个向量中。
6. 迭代器的性能
由于迭代器是惰性求值的,它们在处理大型数据集时非常高效。每次调用 next()
方法时,迭代器只会计算下一个元素,而不会提前计算所有元素。此外,链式操作避免了中间结果的存储,进一步提高了性能。
示例
以下是一个性能优化的示例:
fn main() {let numbers = vec![1, 2, 3, 4, 5];// 使用迭代器的链式操作let sum: i32 = numbers.iter().map(|x| x * 2) // 对每个元素乘以 2.filter(|x| x % 3 != 0) // 过滤掉能被 3 整除的元素.sum(); // 计算总和println!("The sum is {}", sum); // 输出:The sum is 24
}
在这个例子中:
map(|x| x * 2)
对每个元素乘以 2。filter(|x| x % 3 != 0)
过滤掉能被 3 整除的元素。sum()
计算总和,直接返回结果,避免了中间结果的存储。
7. 自定义迭代器
在 Rust 中,可以通过实现 Iterator
特性来创建自定义迭代器。这允许开发者定义自己的迭代逻辑,从而实现更复杂的数据处理。
示例
以下是一个自定义迭代器的示例,用于生成斐波那契数列:
struct Fibonacci {current: u32,next: u32,
}impl Iterator for Fibonacci {type Item = u32;fn next(&mut self) -> Option<Self::Item> {let new_next = self.current + self.next;let new_current = self.next;self.current = new_current;self.next = new_next;Some(self.current)}
}fn main() {let fib = Fibonacci { current: 0, next: 1 };for value in fib.take(10) {println!("{}", value);}
}
在这个例子中:
Fibonacci
是一个自定义迭代器,用于生成斐波那契数列。- 实现了
Iterator
特性,定义了next
方法,用于生成下一个斐波那契数。 - 使用
take(10)
限制生成的斐波那契数的数量。
8. 小结
Rust 的迭代器是一种非常强大和灵活的工具,具有以下特点:
- 惰性求值:迭代器的元素只有在需要时才会被计算,这使得迭代器可以高效地处理大型数据集。
- 链式操作:多个迭代器适配器可以链式调用,实现复杂的操作,同时保持代码简洁。
- 多种适配器:Rust 提供了丰富的迭代器适配器,如
map
、filter
、fold
、collect
等,用于实现各种数据处理逻辑。 - 性能高效:迭代器避免了中间结果的存储,进一步提高了性能。
- 自定义迭代器:开发者可以通过实现
Iterator
特性来创建自定义迭代器,实现更复杂的数据处理逻辑。
通过合理使用迭代器,可以实现高效、简洁且可读性强的数据处理逻辑。
四、综合示例
以下是一个综合展示 Rust 中函数、闭包和迭代器用法的示例程序。这个程序将实现以下功能:
- 定义一个函数,计算两个整数的和。
- 使用闭包对一个整数向量中的每个元素进行加倍操作。
- 使用迭代器适配器对处理后的向量进行过滤和累加操作。
fn main() {// 1. 使用函数计算两个整数的和let a = 5; // i32let b = 3; // i32let sum = add(a, b);println!("The sum of {} and {} is {}", a, b, sum);// 2. 使用闭包对向量中的每个元素进行加倍操作let numbers = [1, 2, 3, 4, 5];let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();println!("Doubled numbers: {:?}", doubled);// 3. 使用迭代器适配器过滤出偶数并计算总和let even_sum: i32 = doubled.iter().filter(|x| *x % 2 == 0).sum();println!("The sum of even numbers is {}", even_sum);
}// 定义一个函数,计算两个整数的和
fn add(a: i32, b: i32) -> i32 {a + b
}
代码说明
-
函数的使用:
- 定义了一个名为
add
的函数,接受两个整数参数并返回它们的和。 - 在
main
函数中调用add
函数,计算a
和b
的和,并打印结果。
- 定义了一个名为
-
闭包的使用:
- 使用
map
迭代器适配器和闭包对numbers
向量中的每个元素进行加倍操作。 - 闭包
|x| x * 2
对每个元素x
进行加倍处理。 - 使用
collect
方法将处理后的结果收集到一个新的向量doubled
中。
- 使用
-
迭代器的使用:
- 使用
filter
迭代器适配器和闭包过滤出doubled
向量中的偶数。 - 使用
sum
方法对过滤后的偶数进行累加操作,并打印结果。
- 使用
输出结果
运行上述程序后,输出如下:
The sum of 5 and 3 is 8
Doubled numbers: [2, 4, 6, 8, 10]
The sum of even numbers is 30
代码的正确性
- 函数
add
正确实现了两个整数的加法。 - 闭包
|x| x * 2
正确地对向量中的每个元素进行了加倍操作。 - 迭代器适配器
map
、filter
和sum
的链式调用正确地实现了对数据的处理和累加操作。
总结
在 Rust 中,函数、闭包和迭代器是实现逻辑和数据处理的核心工具。函数是代码的基本构建块,使用 fn
定义,可以接受参数并返回值,支持泛型和多种调用约定,用于封装逻辑。闭包是匿名函数,可以捕获环境变量,分为 FnOnce
(调用一次)、FnMut
(可变调用)和 Fn
(多次调用),常用于高阶函数和延迟计算。迭代器是用于逐个访问集合元素的接口,惰性求值,支持多种适配器(如 map
、filter
、fold
),可高效处理数据,支持自定义实现。三者结合使用,可实现灵活、高效且安全的编程范式,是 Rust 函数式编程风格的重要体现。