【跟小嘉学 Rust 编程】十三、函数式语言特性:迭代器和闭包

系列文章目录

【跟小嘉学 Rust 编程】一、Rust 编程基础
【跟小嘉学 Rust 编程】二、Rust 包管理工具使用
【跟小嘉学 Rust 编程】三、Rust 的基本程序概念
【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念
【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据
【跟小嘉学 Rust 编程】六、枚举和模式匹配
【跟小嘉学 Rust 编程】七、使用包(Packages)、单元包(Crates)和模块(Module)来管理项目
【跟小嘉学 Rust 编程】八、常见的集合
【跟小嘉学 Rust 编程】九、错误处理(Error Handling)
【跟小嘉学 Rust 编程】十一、编写自动化测试
【跟小嘉学 Rust 编程】十二、构建一个命令行程序
【跟小嘉学 Rust 编程】十三、函数式语言特性:迭代器和闭包

### 文章目录

  • [系列文章目录](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [@[TOC](文章目录)](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [前言](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [一、闭包(Closures)](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.1、闭包(Closures)](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.2、Rust的闭包语法](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.2.1、闭包语法形式](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.2.1、闭包简化形式](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.3、闭包的类型推导](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.4、结构体中的闭包](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5、捕获环境中的值](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.1、捕获环境的值](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.2、闭包对内存的影响](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.2、三种 Fn trait](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.2.1、FnOnce](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.2.2、FnMut](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.2.3、Fn Trait](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.3、move 和 Fn](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.5.4、三种 Fn 的关系](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [1.6、闭包作为函数返回值](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [二、迭代器(Iterators)](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.1、迭代器(Iterators)](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.2、Iterator trait](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.2.1、Iterator trait](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.2.2、next 方法](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.3、迭代方法](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.4、消耗迭代器的方法](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.4.1、sum 方法](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.4.2、collect方法](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.5、迭代器适配器](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.5.1、map](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.5.2、zip](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.5.3、filter](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.5.4、enumerate](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [2.6、自定义迭代器](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [四、性能对比:循环 VS 迭代器](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)
  • [总结](#文章目录 系列文章目录 @TOC 前言 一、闭包(Closures) 1.1、闭包(Closures) 1.2、Rust的闭包语法 1.2.1、闭包语法形式 1.2.1、闭包简化形式 1.3、闭包的类型推导 1.4、结构体中的闭包 1.5、捕获环境中的值 1.5.1、捕获环境的值 1.5.2、闭包对内存的影响 1.5.2、三种 Fn trait 1.5.2.1、FnOnce 1.5.2.2、FnMut 1.5.2.3、Fn Trait 1.5.3、move 和 Fn 1.5.4、三种 Fn 的关系 1.6、闭包作为函数返回值 二、迭代器(Iterators) 2.1、迭代器(Iterators) 2.2、Iterator trait 2.2.1、Iterator trait 2.2.2、next 方法 2.3、迭代方法 2.4、消耗迭代器的方法 2.4.1、sum 方法 2.4.2、collect方法 2.5、迭代器适配器 2.5.1、map 2.5.2、zip 2.5.3、filter 2.5.4、enumerate 2.6、自定义迭代器 四、性能对比:循环 VS 迭代器 总结)

前言

Rust的设计灵感来源于很多现存的语言和技术,其中一个显著的影响就是函数式编程(functional prigramming)。函数式编程风格通常包含将函数作为参数值或其他函数的返回值、将韩式赋值给变量以供之后执行等等。

主要教材参考 《The Rust Programming Language》


一、闭包(Closures)

1.1、闭包(Closures)

Rust的闭包 (Closures)是可以保存进变量或作为参数传递给其他函数的匿名函数。可以在一个地方创建闭包,然后在不同的上下文执行闭包运算。不同函数,闭包允许捕获调用作用域中的值。

例如:

  • 使用函数作为参数进行传递
  • 使用函数作为函数返回值
  • 将函数赋值给变量

1.2、Rust的闭包语法

1.2.1、闭包语法形式

Rust闭包在形式上借鉴了 Smalltalk 和 Ruby 语言,与函数最大的不同就是它的参数是通过 |param| 的形式进行声明的。

示例:闭包语法形式

rust 复制代码
|param1,param2,....|{
	语句1;
	语句2;
	...
	返回表达式
}

1.2.1、闭包简化形式

如果只有一个返回表达式可以简化成如下形式

rust 复制代码
|param|返回表达式

1.3、闭包的类型推导

Rust 是静态语言,因此所有的变量都具有类型,但是得益于编译器的强大类型推导能力,在很多时候我们并不需要显式声明类型,但是函数和必须为所有参数和返回值指定类型。

为了增加代码可读性,有时候我们会显式地给类型进行标注,出于同样的目的,也可以给闭包标注类型。

rust 复制代码
let sum = |x:i32, y:32| -> 32{
	x + y
}

类型推导虽然很好用,但是它不是泛型,当编译器推导出一种类型后,它就会一直使用该类型。

1.4、结构体中的闭包

rust 复制代码
struct Cacher<T> where T: Fn(u32) -> u32 {
	query: T,
	value: Optional<u32>
}

此时 query 就是一个闭包,他的类型是 Fn(u32) -> u32 是一个特征,用来表示T 是一个闭包类型。

1.5、捕获环境中的值

1.5.1、捕获环境的值

闭包可以捕获环境中的值

rust 复制代码
fn main() {
    let x = 4;

    let equal_to_x = |z| z == x;

    let y = 4;

    assert!(equal_to_x(y));
}

如果你使用函数来实现,编译器会告诉我们无法捕获动态环境中的值。

1.5.2、闭包对内存的影响

当闭包从环境中捕获一个值时,会分配内存去存储这些值。对于有些场景来说,这种额外的内存分配会成为一种负担。与之相比,函数就不会去捕获这些环境值,因此定义和使用函数不会拥有这种内存负担。

1.5.2、三种 Fn trait

闭包捕获环境变量有三种途径,恰好对应函数参数的三种传入方式:转移所有权、可变借用、不可变借用,因此Fn Trait 也有三种。

1.5.2.1、FnOnce

该类型的闭包会拿走被捕获变量的所有权。该闭包只能运行一次。

rust 复制代码
fn fn_once<F>(func: F)
where
    F: FnOnce(usize) -> bool,
{
    println!("{}", func(3));
    println!("{}", func(4));
}

fn main() {
    let x = vec![1, 2, 3];
    fn_once(|z|{z == x.len()})
}

此时编译器就会报错,因为不能对已失去所有权的闭包变量进行二次调用。 错误提示告诉我们因为F没有实现Copy Trait ,所以会报错,那么我们添加约束,试试实现了Copy的闭包。

rust 复制代码
fn fn_once<F>(func: F)
where
    F: FnOnce(usize) -> bool + Copy,// 改动在这里
{
    println!("{}", func(3));
    println!("{}", func(4));
}

fn main() {
    let x = vec![1, 2, 3];
    fn_once(|z|{z == x.len()})
}

如果你想强制闭包取得捕获变量的所有权,那么可以在参数列表前面添加 move 关键字,这种用法通常用在闭包的生命周期大于捕获变量的生命周期时,例如将闭包返回或移入其他线程。

rust 复制代码
use std::thread;
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
    println!("Here's a vector: {:?}", v);
});
handle.join().unwrap();

1.5.2.2、FnMut

它是可变借用的方式捕获了环境中的值,因此可以修改该值。

rust 复制代码
fn main() {
    let mut s = String::new();

    let mut update_string =  |str| s.push_str(str);
    update_string("hello");

    println!("{:?}",s);
}

复杂形式

rust 复制代码
fn main() {
    let mut s = String::new();

    let update_string =  |str| s.push_str(str);

    exec(update_string);

    println!("{:?}",s);
}

fn exec<'a, F: FnMut(&'a str)>(mut f: F)  {
    f("hello")
}

1.5.2.3、Fn Trait

它是以不可变借用的方式捕获环境中的值,让我们把上面的代码中的 F 类型修改为Fn。

rust 复制代码
fn main() {
    let mut s = String::new();

    let update_string =  |str| s.push_str(str);

    exec(update_string);

    println!("{:?}",s);
}

fn exec<'a, F: Fn(&'a str)>(mut f: F)  {
    f("hello")
}

从报错中很清晰的看出,我们的闭包实现的是 FnMut 特征,需要的是可变借用,但是在 exec 中却给它标注了 Fn 特征,因此产生了不匹配,再来看看正确的不可变借用方式:

rust 复制代码
fn main() {
    let s = "hello, ".to_string();

    let update_string =  |str| println!("{},{}",s,str);

    exec(update_string);

    println!("{:?}",s);
}

fn exec<'a, F: Fn(String) -> ()>(f: F)  {
    f("world".to_string())
}

1.5.3、move 和 Fn

在上面我们讲解到 move 关键字对于 FnOnce的重要性,实际上使用了 move 的闭包依然可能实现了 Fn 和

Fn Mut 特征。

因为一个闭包实现了哪种 Fn 特征取决于该闭包如何使用被捕获的变量,而不是取决于闭包如何捕获它们。move 本身强调的就是后者,闭包如何捕获变量:

1.5.4、三种 Fn 的关系

实际上,一个闭包不仅仅实现一种 Fn trait,规则如下

  • 所有的闭包都自动实现了 FnOnce 特征,因此任何一个闭包都至少可以被调用一次
  • 没有移出所有捕获变量的所有权的闭包自动实现了 FnMut Trait
  • 不需要对捕获变量进行改变的闭包自动失效了 Fn Trait
rust 复制代码
pub trait Fn<Args> : FnMut<Args> {
    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

pub trait FnMut<Args> : FnOnce<Args> {
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

pub trait FnOnce<Args> {
    type Output;

    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

1.6、闭包作为函数返回值

rust 复制代码
fn factory(x:i32) -> Box<dyn Fn(i32) -> i32> {
    let num = 5;

    if x > 1{
        Box::new(move |x| x + num)
    } else {
        Box::new(move |x| x - num)
    }
}

二、迭代器(Iterators)

2.1、迭代器(Iterators)

迭代器模式:对一系列项执行某些人物,迭代器负责遍历每一项,确定序列何时完成。Rust的迭代器是惰性的,除非调用消费迭代器的方法,否则迭代器本身没有任何效果。

迭代器允许我们迭代一个连续的集合,例如数组、向量、hashMap等。

rust 复制代码
let v1 = vec![1, 2, 3];

let v1_iter = v1.iter();

for val in v1_iter {
    println!("{}", val);
}

2.2、Iterator trait

2.2.1、Iterator trait

所有的迭代器都实现了 Iterator trait,该 Trait 定义于标准库。定义大致如下。

rust 复制代码
pub trait Iterator {
    type Item;

    fn next(&mut self) -> Option<Self::Item>;

    // 省略其余有默认实现的方法
}

2.2.2、next 方法

每次返回迭代器中的一项,返回结果包裹在Some 里面,迭代结束返回None。

rust 复制代码
fn main() {
    let arr = [1, 2, 3];
    let mut arr_iter = arr.into_iter();

    assert_eq!(arr_iter.next(), Some(1));
    assert_eq!(arr_iter.next(), Some(2));
    assert_eq!(arr_iter.next(), Some(3));
    assert_eq!(arr_iter.next(), None);
}

2.3、迭代方法

iter:在不可变引用上创建迭代器

into_iter: 创建的迭代器会获得所有权

iter_mut: 迭代可变的引用

2.4、消耗迭代器的方法

2.4.1、sum 方法

调用 next 方法的方法叫做 消耗型适配器。 例如 :Sum 方法:取得迭代器的所有权。

rust 复制代码
fn main() {
    let v1 = vec![1, 2, 3];

    let v1_iter = v1.iter();

    let total: i32 = v1_iter.sum();

    assert_eq!(total, 6);

    // v1_iter 是借用了 v1,因此 v1 可以照常使用
    println!("{:?}",v1);

    // 以下代码会报错,因为 `sum` 拿到了迭代器 `v1_iter` 的所有权
    // println!("{:?}",v1_iter);
}

2.4.2、collect方法

rust 复制代码
use std::collections::HashMap;
fn main() {
    let names = ["sunface", "sunfei"];
    let ages = [18, 18];
    let folks: HashMap<_, _> = names.into_iter().zip(ages.into_iter()).collect();

    println!("{:?}",folks);
}

zip 是一个迭代器适配器,它的作用就是将两个迭代器的内容压缩到一起,形成 Iterator<Item=(ValueFromA, ValueFromB)> 这样的新的迭代器,在此处就是形如 [(name1, age1), (name2, age2)] 的迭代器。

然后再通过 collect 将新迭代器中(K, V) 形式的值收集成 HashMap<K, V>,同样的,这里必须显式声明类型,然后 HashMap 内部的 KV 类型可以交给编译器去推导,最终编译器会推导出 HashMap<&str, i32>,完全正确!

2.5、迭代器适配器

2.5.1、map

既然消费者适配器是消费掉迭代器,然后返回一个值。那么迭代器适配器,顾名思义,会返回一个新的迭代器,这是实现链式方法调用的关键:v.iter().map().filter()...。

与消费者适配器不同,迭代器适配器是惰性的,意味着你需要一个消费者适配器来收尾,最终将迭代器转换成一个具体的值:

rust 复制代码
let v1: Vec<i32> = vec![1, 2, 3];

let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();

assert_eq!(v2, vec![2, 3, 4]);

2.5.2、zip

2.5.3、filter

2.5.4、enumerate

使用 enumerate 方法可以获取迭代时的索引。
rust 复制代码
let v = vec![1u64, 2, 3, 4, 5, 6];
for (i,v) in v.iter().enumerate() {
    println!("第{}个值是{}",i,v)
}

2.6、自定义迭代器

自定义迭代器很简单,我们只需要实现 Iterator 特征 以及next 方法即可。实际上  Iterator 之中还有其他方法,其他方法都有默认实现,无需手动去实现。
rust 复制代码
impl Iterator for Counter {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

四、性能对比:循环 VS 迭代器

迭代器是 Rust的零成本抽象(zero-cost abstractions) 之一,意味着抽象并不会引入运行时开销。

总结

以上就是今天要讲的内容

相关推荐
k09332 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯10 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue12 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧14 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
测试界的酸菜鱼26 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
晨曦_子画35 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend43 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
假装我不帅1 小时前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc
神仙别闹1 小时前
基于ASP.NET+SQL Server实现简单小说网站(包括PC版本和移动版本)
后端·asp.net