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

学习笔记十五——rust柯里化,看不懂 `fn add(x) -> impl Fn(y)` 的同学点进来!

🧠 Rust 柯里化从零讲透:看不懂 fn add(x) -> impl Fn(y) 的同学点进来!

🍔 一、什么是柯里化?先用一个超好懂的生活比喻

假设你在点一个汉堡:

你说:我要点一个鸡腿汉堡!
店员说:好的,请先选肉 → 鸡腿
再选酱料 → 辣酱
最后选芝士 → 加!

是不是你并没有一次性说完,而是一步一步选项配置完成?每次传一个参数。

这就是“柯里化”的思想:

把一个需要多个参数的函数,变成“一层一层传一个参数”的函数结构。


💡 二、我们来对比看:正常函数 VS 柯里化函数

// 普通函数(一次性传两个参数)
fn add(x: i32, y: i32) -> i32 {x + y
}

调用方式是:

let result = add(2, 3);  // 直接给两个参数,得到结果 5

柯里化版本写法是这样的:

fn add(x: i32) -> impl Fn(i32) -> i32 {move |y| x + y
}

🔍 三、这一句到底怎么读?我们逐字逐句拆解!

📘 原始代码:

fn add(x: i32) -> impl Fn(i32) -> i32 {move |y| x + y
}

🧩 第一步:函数签名部分解读

fn add(x: i32)

意思是:这个函数叫 add,它接收一个参数 x,类型是 i32


🧩 第二步:箭头 -> 后面部分

-> impl Fn(i32) -> i32

这部分表示:

函数的返回值是 一个“能接收 i32,并返回 i32”的函数

说人话就是:

你调用 add(10) 得到的,并不是一个数字,而是一个函数!

而这个函数就像这样:

|y| 10 + y

这个函数“等着你传第二个参数 y”,然后它会用之前的 x = 10 加上 y,返回结果。


🧩 第三步:move |y| x + y 是什么意思?

这句其实是 Rust 的“闭包写法”,也叫“匿名函数”:

move |y| x + y

拆开解释:

部分解释
move让闭包把外部变量(比如 x)带进来,封装进去
|y|这是闭包的参数(就像 fn(y))
x + y闭包的执行体逻辑:x 和 y 相加

所以这个闭包表示:

“我是一个能接受 y 的函数,我知道外部的 x,然后返回 x + y 的结果。”


🧪 举个完整例子,来看怎么使用这个柯里化函数:

fn add(x: i32) -> impl Fn(i32) -> i32 {move |y| x + y
}fn main() {let add_10 = add(10);// ↑ 第一步,传入参数 x = 10,返回一个闭包//   这个闭包相当于 |y| 10 + ylet result = add_10(5);// ↑ 第二步,再传入 y = 5//   执行的是:10 + 5 = 15println!("结果是: {}", result);  // 输出 结果是: 15
}

🧱 四、图解:柯里化是怎么“层层返回”的?

fn add(x)
↓
返回一个函数 |y| {用到之前的 x + 当前的 y
}

你可以理解为:第一次函数调用“定制好了逻辑”,但还没执行;第二次才执行。


💭 五、为什么我们明明没有看到 y 参数,却能传 y?

这是**“闭包”**的关键作用。

闭包 move |y| x + y 是个“函数”,你可以存它、传它、执行它。

当你写:

let add_10 = add(10);

这个 add_10 是个函数,你可以像下面这样用它:

add_10(1)
add_10(2)
add_10(100)

每次传进去的就是参数 y

这个 y 就是在你真正执行闭包的时候才“出现”。


✅ 六、你现在可以这样理解这句代码:

fn add(x: i32) -> impl Fn(i32) -> i32 {move |y| x + y
}

🔹 它是一个“做加法的函数工厂”:

你告诉它 x 它就给你返回一个“只差 y”的函数。
你什么时候需要加 y,再传进去,它才给你结果。


🧰 七、为什么要这么麻烦搞柯里化?

因为柯里化有这些强大优势:

应用场景优势
🎯 提前绑定参数可以预设 x,只改 y,比如 add_10 = add(10)
🧱 组合函数可以把多个闭包组合成管道式处理函数
🧩 配置默认项比如封装 IP,后续只改端口(见下文)
📦 构造工厂函数像“做函数的函数”,可复用、易测试

🔁 八、再看两个实用场景


🟢 配置化参数:绑定一部分值

fn connect(ip: &str) -> impl Fn(u16) -> String {let ip = ip.to_string(); // 复制字符串所有权进闭包move |port| format!("连接 {}:{}", ip, port)
}

用法:

let local = connect("127.0.0.1");
println!("{}", local(8080));  // 连接 127.0.0.1:8080
println!("{}", local(3000));  // 连接 127.0.0.1:3000

优势:IP 只写一次,port 可动态传。更灵活、结构清晰


🟢 函数组合:先加再乘

fn add(x: i32) -> impl Fn(i32) -> i32 {move |y| x + y
}
fn mul(x: i32) -> impl Fn(i32) -> i32 {move |y| x * y
}fn main() {let step1 = add(2); // +2let step2 = mul(3); // *3let result = step2(step1(4)); // (4 + 2) * 3 = 18println!("组合结果: {}", result);
}

📘 九、总结:你现在该怎么读懂这一句代码?

fn add(x: i32) -> impl Fn(i32) -> i32 {move |y| x + y
}

✅ 翻译成人话:

“我这个函数 add,先让你告诉我 x,我会返回一个新的函数,这个新函数能接收 y,然后把 x + y 返回。”

它是个两步操作函数,每步只干一件事。


🧠 十、关键记忆方法

方法说明
📦 想象闭包是“能记住变量的盒子”`move
🔁 柯里化就是函数拆分,每层一个参数f(x, y) 变成 f(x)(y)
🧠 多举例,多写“函数返回函数”的结构自己模仿写“加法器、乘法器、配置函数”等

如果你想,我也可以做一个动画演示图,帮助你形象化理解“add(10) 返回函数”的过程

相关文章:

学习笔记十五——rust柯里化,看不懂 `fn add(x) -> impl Fn(y)` 的同学点进来!

🧠 Rust 柯里化从零讲透:看不懂 fn add(x) -> impl Fn(y) 的同学点进来! 🍔 一、什么是柯里化?先用一个超好懂的生活比喻 假设你在点一个汉堡: 你说:我要点一个鸡腿汉堡! 店员…...

定制化突围:遨游防爆手机的差异化竞争策略

在石油、化工、矿山等危险作业场景中,随着工业智能化与安全生产需求的升级,行业竞争逐渐从单一产品性能的比拼转向场景化解决方案的深度较量。遨游通讯以九重防爆标准为技术底座,融合多模稳控系统与全景前瞻架构,开辟出"千行…...

【Java学习笔记】进制与进制转换

进制与进制转换 一、进制介绍 二进制:0、1,满 2 进 1,以 0b 或 0B 开头。 十进制:0-9,满 10 进 1。 八进制:0-7,满 8 进 1,以数字 0 开头表示。 十六进制:0-9 及 A(10…...

士兵乱斗(贪心)

问题 B: 士兵乱斗 - USCOJ...

【C++面向对象】封装(下):探索C++运算符重载设计精髓

🔥个人主页 🔥 😈所属专栏😈 每文一诗 💪🏼 年年岁岁花相似,岁岁年年人不同 —— 唐/刘希夷《代悲白头翁》 译文:年年岁岁繁花依旧,岁岁年年看花之人却不相同 目录 C运…...

JVM初探——走进类加载机制|三大特性 | 打破双亲委派SPI机制详解

目录 JVM是什么? 类加载机制 Class装载到JVM的过程 装载(load)——查找和导入class文件 链接(link)——验证、准备、解析 验证(verify)——保证加载类的正确性 准备(Prepare&…...

[图论]Kruskal

Kruskal 本质:贪心,对边进行操作。存储结构:边集数组。适用对象:可为负权图,可求最大生成树。核心思想:最短的边一定在最小生成树(MST)上,对最短的边进行贪心。算法流程:对全体边集…...

UML-饮料自助销售系统(无法找零)序列图

一、题目: 在饮料自动销售系统中,顾客选择想要的饮料。系统提示需要投入的金额,顾客从机器的前端钱币口投入钱币,钱币到达钱币记录仪,记录仪更新自己的选择。正常时记录仪通知分配器分发饮料到机器前端,但可…...

Nginx Http配置整理

一、nginx 配置参数: server {#SSL 默认访问端口号为 443listen 443 ssl;#请填写绑定证书的域名server_name cloud.tencent.com; #请填写证书文件的相对路径或绝对路径ssl_certificate cloud.tencent.com_bundle.crt; #请填写私钥文件的相对路径或绝对路径ssl_cer…...

爬虫利器SpiderTools谷歌插件教程v1.0.0!!!web端JavaScript环境检测!!!

SpiderTools谷歌插件教程v1.0.0 一、SpiderTools简介二、下载通道三、插件介绍四、插件使用五、工具函数使用 一、SpiderTools简介 SpiderTools主要用于检测和监控网页的JavaScript运行环境。该插件可以帮助开发者更好地查看网页运行环境,特别是在处理复杂的前端环…...

计算机视觉算法实战——基于YOLOv8的农田智能虫情测报灯害虫种类识别系统开发指南

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​ ​​​​​​​​​ ​​ 一、智能虫情监测领域概述 1.1 农业虫害防治现状 全球每年因虫害造成的粮食损失达20%-40%,我…...

14-算法打卡-哈希表-基本概念-第十四天

1 基本概念 1.1 哈希表 百度百科解释: 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快…...

趣味编程之分布式系统:负载均衡的“雨露均沾“艺术

#此篇文章由Deepseek大力支持😋 凌晨三点,西二旗某火锅店后厨—— “羊肉卷走3号桌!” “肥牛卷去7号!” “虾滑优先给VIP区!” 我蹲在传菜口的监控屏幕前,看着机器人服务生们忙而不乱地穿梭。突然间&am…...

第十六届蓝桥杯大赛软件赛省赛 C++ 大学 B 组 部分题解

赛时参加的是Python组,这是赛后写的题解,还有两题暂时还不会,待更新 题目链接题目列表 - 洛谷 | 计算机科学教育新生态 A 移动距离 答案:1576 C 可分解的正整数 Python3 import itertools from functools import cmp_to_ke…...

考研数据结构之顺序查找、折半查找与分块查找详解(包含真题及解析)

考研数据结构之顺序查找、折半查找与分块查找详解 一、顺序查找(Sequential Search) 1.1 基本思想 顺序查找是最基础的查找算法,通过遍历数据集合逐个比较目标值与当前元素,直到找到匹配项或遍历结束。其核心特点是&#xff1a…...

英文查重的时候参考文献显示重复是怎么回事?

像上图这样参考文献部分有颜色的情况,是属于参考文献没有排除干净的问题。 如何解决这样的问题? 首先第一步,先确认该报告是不是排除参考文献的版本; 第二步,如果是排除参考文献的版本,且参考文献仍然有…...

八股文---MySQl(3)

目录 12.事务的特性是什么?可以详细说一下吗? 回答 13并发事务带来哪些问题?怎么解决这些问题呢?MySQL的默认隔离级别是? 脏读:一个事务读到另外一个事务还没有提交的数据。 不可重复读:一个…...

基于labview的钢琴程序设计

部分程序如下 按照上图子vi更改输出频率即可 若需完整程序可以联系我...

国内网络设备厂商名单(List of Domestic Network Equipment Manufacturers)

国内网络设备厂商名单 运维工程师必须广泛熟悉国内外各大厂商的设备,深入掌握其应用场景、功能特点及优势。这不仅有助于在故障排查时迅速定位问题,还能在系统设计、优化与升级中做出更合理的决策。对设备特性的精准把握,能够显著提升运维效…...

基于CNN+ViT的蔬果图像分类实验

本文只是做一个简单融合的实验,没有任何新颖,大家看看就行了。 1.数据集 本文所采用的数据集为Fruit-360 果蔬图像数据集,该数据集由 Horea Mureșan 等人整理并发布于 GitHub(项目地址:Horea94/Fruit-Images-Datase…...

高级语言调用C接口(五)结构体(3)-arkts

上一篇文章提到了,arkts和C接口之前还有一个Napi层,这层代码最大的优势就是C/C编码,这样,我们只需要把数据通过Json格式传递到Napi层,Napi层再定义一个结构体并赋值即可。arkts层是TypeScript代码,想定义成…...

【虚幻C++笔记】接口

目录 概述创建接口 概述 简单的说,接口提供一组公共的方法,不同的对象中继承这些方法后可以有不同的具体实现。任何使用接口的类都必须实现这些接口。实现解耦解决多继承的问题 创建接口 // Fill out your copyright notice in the Description page o…...

【MCP】第一篇:MCP协议深度解析——大模型时代的“神经连接层“架构揭秘

【MCP】第一篇:MCP协议深度解析——大模型时代的"神经连接层"架构揭秘 一、什么是MCP?二、为什么需要MCP?三、MCP的架构四、MCP与AI交互的原理4.1 ReAct(Reasoning Acting)模式4.2 Function Calling 模式 五…...

实时模式下 libaom 与 x264 编码对比实验

前沿 理论基础:在相同视频质量下,AV1的压缩率比H.264高约30%-50%。实时模式:视频编码中的实时模式,其核心目标是平衡编码效率与延迟要求,尤其在视频会议、直播、实时通信等场景中至关重要。 低延迟要求:编…...

学习海康VisionMaster之矩形检测

这几天太忙了,好几天没有学习了,今天终于空下来了,继续学习之路吧。 一:进一步学习了 今天学习下VisionMaster中的矩形检测,这个一开始我以为是形态学方面的检测,实际操作下来其实还是边缘直线的衍生应用&…...

解决前端vue项目在linux上,npm install,node-sass 安装失败的问题

Unable to save binary /var/lib/jenkins/workspace/xxx/node_modules/node-sass/vendor/linux-x64-72 : Error: EACCES: permission denied, mkdir ‘/var/lib/jenkins/workspace/x/node_modules/node-sass/vendor’ 这个是node-sass安装失败导致的。 #将npm的默认仓库更改为…...

C Primer Plus 第6版 编程练习——第3章

1、通过试验(即编写带有此类问题的程序)观察系统如何处理整数上道、浮占数上溢和浮点数下溢的 int main(int argc, char** argv) {int intMax 2147483647;float floatMax 3.402823466e38f;float floatMin -3.402823466e38f;printf("intMax:%d, …...

十倍开发效率 - IDEA插件之 Mybatis Log Free

提高效率不是为了完成更多任务,而是为了有充足的时间摸鱼 快速体验 MyBatis Log Free 支持打印执行的 SQL(完整的SQL,没有占位符的)。 没有使用 MyBatis Log Free 的开启日志打印是这样的: 用了 MyBatis Log Free 后…...

手动安装 VMware Tools 并设置虚拟机共享 Windows 文件夹

前言:在当今数字化的工作环境中,虚拟机技术为我们提供了强大的灵活性和便利性。VMware 作为虚拟化领域的佼佼者,其虚拟机软件被广泛应用于开发、测试和日常工作中。然而,许多用户在使用 VMware 虚拟机时,会遇到一个常见…...

(免费)flask调用讯飞星火AI,实现websocket

本文章可借鉴学习,不可直接盗用 接入ai要获取ID,Secret,Key,和接口地址,由于我们服务接口类型是websocket,所以要获取相应的接口地址。(千万不要复制粘贴到http的了) 还要获取doma…...