当前位置: 首页 > article >正文

学习笔记十二——Rust 高阶函数彻底入门(超详细过程解析 + 每步数值追踪)

💡 彻底搞懂 Rust 高阶函数!新手最容易卡住的语法 + 调用流程全讲透(含逐步拆解)

Rust 函数式编程中有一个常见却经常让人懵的概念:高阶函数(Higher-Order Function)
一看到 fn(i32) -> i32|x| x + 1f(f(x)) 很多人都想关掉编辑器 😢

别担心!这篇文章是为完全零基础的新手写的,不仅讲清楚高阶函数是什么、怎么用、每一步调用发生了什么,还会带你用“代入值”一步步算清楚过程。


🧠 什么是高阶函数?为什么叫“高阶”?

我们常写的普通函数,只是“接收数据 → 处理 → 返回结果”。

高阶函数是一种“接收函数 / 返回函数”的函数,意思是它可以把函数当作数据一样操作!

通俗点讲,高阶函数能做两件事:

  1. 把函数作为参数传入
  2. 把函数作为返回值返回出来

这就是“比普通函数高一阶”的原因!


📌 第一次看到 apply_twice 是不是很迷?我们一步步拆解

来看下面这个典型示例:

fn apply_twice(f: fn(i32) -> i32, x: i32) -> i32 {f(f(x))
}

别慌,我们来逐句解释每个部分到底是什么意思


🔍 f: fn(i32) -> i32 到底是啥?

这表示 f 是一个函数,它的“输入是 i32,输出也是 i32”。

就像这样一个函数:

fn add_one(n: i32) -> i32 {n + 1
}

它就符合 fn(i32) -> i32 的格式。


🧠 再看整行函数定义:

fn apply_twice(f: fn(i32) -> i32, x: i32) -> i32
  • f 是一个函数
  • x 是一个普通的整数
  • 返回值类型是 i32

也就是说:你把一个函数和一个数字交给我,我来帮你“连续调用两次这个函数”。


🧪 然后看函数体:f(f(x)) 是什么逻辑?

拆成两步理解:

  1. f(x):先对 x 调用一次 f
  2. f(f(x)):再把结果作为新参数,再次调用 f

是不是像数学里的 f(f(x))?


✅ 用 add_one + apply_twice 的完整示例来演示

fn add_one(n: i32) -> i32 {println!("调用 add_one({})", n);n + 1
}fn apply_twice(f: fn(i32) -> i32, x: i32) -> i32 {println!("第一次调用:f({})", x);let first = f(x);println!("第一次结果:{}", first);println!("第二次调用:f({})", first);let second = f(first);println!("第二次结果:{}", second);second
}fn main() {let result = apply_twice(add_one, 5);println!("最终结果是:{}", result);
}

✅ 输出结果:

第一次调用:f(5)
调用 add_one(5)
第一次结果:6
第二次调用:f(6)
调用 add_one(6)
第二次结果:7
最终结果是:7

✅ 过程追踪表:

步骤表达式
第一次调用f(x) = add_one(5)6
第二次调用f(6) = add_one(6)7
返回值7

🧠 闭包 |x| x * 2 到底是个啥?

你可能看到过这种写法:

let double = |x| x * 2;

这其实就是一个“没有名字的函数”,我们叫它闭包匿名函数

和普通函数的写法效果一样:

fn double(x: i32) -> i32 {x * 2
}

✅ 闭包支持捕获外部变量:

fn main() {let multiplier = 3;let multiply = |x: i32| x * multiplier; // multiplier 是从外面拿到的println!("3 * 4 = {}", multiply(4)); // 输出:12
}

闭包最强大的一点:可以捕获函数外的变量并使用


🔁 函数还能作为“返回值”?可以做函数工厂!

看这个例子:

fn make_adder(n: i32) -> impl Fn(i32) -> i32 {move |x| x + n
}fn main() {let add_five = make_adder(5);   // 生成一个加5的函数println!("{}", add_five(10));   // 输出:15
}
步骤说明
make_adder(5)返回闭包 `
add_five(10)实际是 10 + 5 = 15

✅ 一图总结:Rust 高阶函数核心语法

表达式含义示例
f: fn(i32) -> i32参数是函数apply_twice(add_one, 5)
f(f(x))连续调用 f 两次add_one(add_one(5))
|x| x * 2闭包(匿名函数)let f = |x| x * 2;
move |x| x + n捕获外部变量的闭包make_adder(n)
impl Fn(...)函数返回值是闭包-> impl Fn(i32) -> i32

✅ 总结回顾

Rust 中的高阶函数,是编程中的“套路神器”:

特点用途
✅ 抽象逻辑提取公共流程
✅ 更简洁map/filter 替代 for
✅ 更安全闭包拥有环境,不容易出错
✅ 更组合函数传来传去,模块组合更自由

相关文章:

学习笔记十二——Rust 高阶函数彻底入门(超详细过程解析 + 每步数值追踪)

💡 彻底搞懂 Rust 高阶函数!新手最容易卡住的语法 调用流程全讲透(含逐步拆解) Rust 函数式编程中有一个常见却经常让人懵的概念:高阶函数(Higher-Order Function) 一看到 fn(i32) -> i32、…...

电脑的品牌和配置

我的笔记本是2020年买的,之前的订单找不到了,就知道是联想,不清楚具体的配置。 本文来源:腾讯元宝 检查系统信息(Windows) 这通常是 ​​联想(Lenovo)​​ 的型号代码。 81XV 是联想…...

Redis面试——常用命令

一、String (1)设置值相关命令 1.1.1 SET 功能:设置一个键值对,如果键已存在则覆盖旧值语法: SET key value [EX seconds] [PX milliseconds] [NX|XX]EX seconds:设置键的过期时间为 seconds 秒 PX milli…...

Swin-Transformer-UNet改进:融合Global-Local Spatial Attention (GLSA) 模块详解

目录 1.模块概述 2.swinUNet网络 3. 完整代码 1.模块概述 Global-Local Spatial Attention (GLSA) 是一种先进的注意力机制模块,专为计算机视觉任务设计,能够同时捕捉全局上下文信息和局部细节特征。 该模块通过创新的双分支结构和自适应融合机制,显著提升了特征表示能…...

ubuntu 向右拖动窗口后消失了、找不到了

这是目前单显示器的设置,因为实际只有1个显示器,之前的设置如下图所示,有2个显示器,一个主显示器,一个23寸的显示器 ubuntu 22.04 系统 今天在操作窗口时,向右一滑,发现这个窗口再也不显示了、找…...

大语言模型(LLMs)中的强化学习(Reinforcement Learning, RL)

第一部分:强化学习基础回顾 在深入探讨LLMs中的强化学习之前,我们先快速回顾一下强化学习的核心概念,确保基础扎实。 1. 强化学习是什么? 强化学习是一种机器学习范式,目标是让智能体(Agent)…...

2025最新版微软GraphRAG 2.0.0本地部署教程:基于Ollama快速构建知识图谱

一、前言 微软近期发布了知识图谱工具 GraphRAG 2.0.0,支持基于本地大模型(Ollama)快速构建知识图谱,显著提升了RAG(检索增强生成)的效果。本文手把手教你如何从零部署,并附踩坑记录和性能实测…...

泛型算法——只读算法(一)

在 C 标准库中,泛型算法的“只读算法”指那些 不会改变它们所操作的容器中的元素,仅用于访问或获取信息的算法,例如查找、计数、遍历等操作。 accumulate std::accumulate()是 C 标准库**numeric**头文件中提供的算法,用于对序列…...

Redis的常见数据类型

Redis 提供了多种数据类型,以满足不同的应用场景。以下是 Redis 的主要数据类型及其应用场景: 字符串(String): 描述:最基本的数据类型,存储单个键值对,值可以是字符串、整数或浮点数…...

Mybatis中dao(mapper)层几种传参方式

一、SQL语句中接收参数的方式有两种: 1、 #{}预编译 (可防止sql注入) 2、${}非预编译(直接拼接sql,不能防止sql注入) #{}和${}的区别是什么? #{} 占位符,相当于?,sql预编译&…...

网络安全知识点2

1.虚拟专用网VPN:VPN用户在此虚拟网络中传输私网流量,在不改变网络现状的情况下实现安全,可靠的连接 2.VPN技术的基本原理是利用隧道技术,对传输报文进行封装,利用VPN骨干网建立专用数据传输通道,实现报文…...

libevent服务器附带qt界面开发(附带源码)

本章是入门章节,讲解如何实现一个附带界面的服务器,后续会完善与优化 使用qt编译libevent源码演示视频qt的一些知识 1.主要功能有登录界面 2.基于libevent实现的服务器的业务功能 使用qt编译libevent 下载这个,其他版本也可以 主要是github上…...

智能体数据分析

数据概览: 展示智能体的累计对话次数、累计对话用户数、对话满意度、累计曝光次数。数据分析: 统计对话分析、流量分析、用户分析、行为分析数据指标,帮助开发者完成精准的全面分析。 ps:数据T1更新,当日12点更新前一天…...

[特殊字符] UnionFS(联合文件系统)原理解析:容器背后的存储技术

🔍 UnionFS(联合文件系统)原理解析:容器背后的存储技术 💡 什么是 UnionFS? UnionFS(联合文件系统) 是一种可以将多个不同来源的文件系统“合并”在一起的技术。它的核心思想是&am…...

STM32(M4)入门: 概述、keil5安装与模板建立(价值 3w + 的嵌入式开发指南)

前言:本教程内容源自信盈达教培资料,价值3w,使用的是信盈达的405开发版,涵盖面很广,流程清晰,学完保证能从新手入门到小高手,软件方面可以无基础学习,硬件学习支持两种模式&#xff…...

采用若依vue 快速开发系统功能模块

文章目录 运行若依项目 科室管理科室查询-后端代码实现科室查询-前端代码实现科室名称状态搜索科室删除-后端代码实现科室删除-前端代码实现科室新增-后端代码实现科室新增-前端代码实现科室修改-后端代码实现前端代码实现角色权限实现 运行若依项目 运行redis 创建数据库 修改…...

HTML:表格数据展示区

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>人员信息表</title><link rel"styl…...

WIN11运行游戏时出现“ms-gamingoverlay”弹框的问题

针对WIN11运行游戏时出现“ms-gamingoverlay”弹框的问题&#xff0c;以下是经过验证的多种解决方法&#xff0c;结合不同场景需求提供对应方案&#xff1a; 一、关闭系统内置的游戏录制功能 禁用Xbox Game Bar及游戏录制 • 进入系统设置&#xff08;WinI&#xff09;→ 左侧选…...

Oracle测试题目及笔记(单选)

所有题目来自于互联网搜索 当 Oracle 服务器启动时&#xff0c;下列哪种文件不是必须的&#xff08;D&#xff09;。 A&#xff0e;数据文件 B&#xff0e;控制文件 C&#xff0e;日志文件 D&#xff0e;归档日志文件 数据文件、日志文件-在数据库的打开阶段使用 控制文件-在数…...

Jmeter创建使用变量——能够递增递减的计数器

Jmeter创建使用变量——能够递增递减的计数器 如下图所示&#xff0c;创建一个 取值需限定为0 2 4这三个值内的变量。 Increment&#xff1a;每次迭代后 递增的值&#xff0c;给计数器增加的值 Maximum value&#xff1a;计数器的最大值&#xff0c;如果超过最大值&#xff0…...

【LeetCode基础算法】滑动窗口与双指针

定长滑动窗口 总结&#xff1a;入-更新-出。 入&#xff1a;下标为 i 的元素进入窗口&#xff0c;更新相关统计量。如果 i<k−1 则重复第一步。 更新&#xff1a;更新答案。一般是更新最大值/最小值。 出&#xff1a;下标为 i−k1 的元素离开窗口&#xff0c;更新相关统计量…...

数据结构之BFS广度优先算法(腐烂的苹果)

队列这个数据结构在很多场景下都有使用&#xff0c;比如在实现二叉树的层序遍历&#xff0c;floodfill问题(等等未完成)中&#xff0c;都需要借助队列的先进先出特性&#xff0c;下面给出这几个问题的解法 经典的二叉树的层序遍历 算法图示&#xff0c;以下图所示的二叉树为例…...

道可云人工智能每日资讯|首届世界人工智能电影节在法国尼斯举行

道可云元宇宙每日简报&#xff08;2025年4月15日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 杭州《西湖区打造元宇宙产业高地的扶持意见》发布 杭州西湖区人民政府印发《西湖区打造元宇宙产业高地的扶持意见》。该意见已于4月4日正式施行&#xff0c;有效期至…...

火车头采集动态加载Ajax数据(无分页瀑布流网站)

为了先填充好数据在上线&#xff0c;在本地搭建了一个网站&#xff0c;并用火车头采集数据填充到里面。 开始很上手&#xff0c;因为找的网站的分类中是有分页的。很快捷的找到页面标识。 但是问题来了&#xff0c;如今很多网站都是采用的Ajax加载数据&#xff0c;根本没有分…...

Android Jetpack是什么与原生android 有什么区别

Android Jetpack是什么 Android Jetpack是Google推出的一套开发组件工具集,旨在帮助开发者更高效地构建高质量的Android应用。它包含多个库和工具,被分为架构、用户界面、行为和基础四大类。以下是一些Android Jetpack的示例: 架构组件 ViewModel:用于以生命周期的方式管理…...

Android Retrofit 框架适配器模块深入源码分析(五)

Android Retrofit 框架适配器模块深入源码分析 一、引言 在 Android 开发中&#xff0c;网络请求是一个常见且重要的功能。Retrofit 作为一个强大的网络请求框架&#xff0c;以其简洁的 API 和高度的可定制性受到了广泛的欢迎。适配器模块&#xff08;CallAdapter&#xff09…...

Node.js模块化与npm

目录 一、模块化简介 二、CommonJS 规范 1. 基本语法 2. 导出模块 3. 导入模块 三、ECMAScript 标准&#xff08;ESM&#xff09; 1. 启用 ESM 一、默认导出与导入 1. 基本语法 2. 默认导出&#xff08;每个模块仅一个&#xff09; 3. 默认导入 二、命名导出与导入…...

nginx中的代理缓存

1.缓存存放路径 对key取哈希值之后&#xff0c;设置cache内容&#xff0c;然后得到的哈希值的倒数第一位作为第一个子目录&#xff0c;倒数第三位和倒数第二位组成的字符串作为第二个子目录&#xff0c;如图。 proxy_cache_path /xxxx/ levels1:2 2.文件名哈希值...

【前端vue生成二维码和条形码——MQ】

前端vue生成二维码和条形码——MQ 前端vue生成二维码和条形码——MQ一、安装所需要的库1、安装qrcode2、安装jsbarcode 二、使用步骤1、二维码生成2、条形码生成 至此&#xff0c;大功告成&#xff01; 前端vue生成二维码和条形码——MQ 一、安装所需要的库 1、安装qrcode 1…...

flutter 桌面应用之窗口自定义

在开发桌面软件的时候我们经常需要配置软件的窗口的大小以及位置 我们有两个框架选择:window_manager和bitsdojo_window 对比bitsdojo_window 特性bitsdojo_windowwindow_manager自定义标题栏✅ 支持❌ 不支持控制窗口行为&#xff08;大小/位置&#xff09;✅&#xff08;基本…...