学习笔记十六——Rust Monad从头学

🧠 零基础也能懂的 Rust Monad:逐步拆解 + 三大定律通俗讲解 + 实战技巧


📣 第一部分:Monad 是什么?

Monad 是一种“包值 + 链操作 + 保持结构”的代码模式,用来处理带上下文的值,并方便连续处理。

✅ 用人话怎么说?

你可以把 Monad 想成“装了值的容器”,它还带了一套通用的处理流程,能帮你做以下三件事:

  1. 包裹值:比如用户输入 5,你包装成 Some(5),表示“有值”。
  2. 自动判断是否处理:值存在就处理,不存在就跳过。
  3. 统一结构,不出错:你不管怎么处理,最后结构还保持不变(比如一直是 Option<T>)。

🧩 第二部分:Monad 三大组成要素

这三样东西是判断一个类型是不是 Monad 的“标准配件”。

要素名称用通俗话解释Rust 中的样子
① 包装器类型构造器把值“装进盒子”Some(x)Ok(x)async { x }
② 起点函数单位函数(unit)把普通值变成最简单的 Monad 容器Some(x)Ok(x)
③ 链接器绑定函数(bind)如果有值就继续调用下一个操作.and_then(...)

这些特性让我们可以放心大胆地“串”代码逻辑。


🔍 第三部分:什么叫“上下文”和“结构保持不变”?

例子上下文的含义
Option<T>这个值可能为空(None)
Result<T,E>这个操作可能失败
Future<T>这个值未来才会得到

✅ 举个例子:

Some(5).and_then(|x| Some(x + 1)).and_then(|y| Some(y * 2))

这里的每一步都保留了 Option 结构,不会突然变成裸值 i32。这就叫结构不变


🧪 第四部分:三大定律彻底通俗讲清楚!

✅ 左单位律(Left Identity)

定义:

unit(x).bind(f) == f(x)

用人话说:

把值放进盒子再处理,和你直接处理这个值,没区别!

示例:

fn f(x: i32) -> Option<i32> {Some(x + 1)
}let a = Some(5).and_then(f); // 左边:unit(x).bind(f)
let b = f(5);                // 右边:直接调用 f(x)assert_eq!(a, b);            // 都是 Some(6)

口诀:“左边装进去再处理,和直接处理一样。”


✅ 右单位律(Right Identity)

定义:

m.bind(unit) == m

用人话说:

如果你对值“啥也不干就原样放回去”,等于什么都没做。

示例:

let x = Some("hi");
let result = x.and_then(|v| Some(v)); // 就是 unit(v)assert_eq!(result, x); // 不变

口诀:“右边原样返回,啥也没改变。”


✅ 结合律(Associativity)

定义:

m.bind(f).bind(g) == m.bind(|x| f(x).bind(g))

用人话说:

不管你是“先 f 后 g”还是“把 f 和 g 合起来一起处理”,结果一样!

示例:

fn f(x: i32) -> Option<i32> { Some(x + 1) }
fn g(x: i32) -> Option<i32> { Some(x * 2) }let m = Some(3);
let a = m.and_then(f).and_then(g);
let b = m.and_then(|x| f(x).and_then(g));assert_eq!(a, b); // 都是 Some(8)

理解要点:

  • f(x) 是第一步
  • g(...) 是第二步
  • 两种写法是“逐步绑定”和“整体组合”的区别

口诀:“多步绑定能拆合,合成一起也不差。”


📘 第五部分:从例子理解 Option 是怎么应用 Monad 的

fn validate_email(email: Option<String>) -> Option<String> {email.and_then(|e| {if e.contains("@") {Some(e)} else {None}})
}

每行拆解:

  • Option<String>:这个邮箱可能存在也可能不存在
  • .and_then(...):如果有值就执行闭包,否则直接 None
  • |e| {...}:取出值 e 后判断是否含有 @
  • 满足条件返回 Some(e),否则返回 None

体现了什么?

  • ✅ 用 Some(email) 开始:unit(x)
  • ✅ 用 .and_then(...) 处理:bind
  • ✅ 最后返回的仍是 Option<String>:结构不变

🔧 第六部分:.map() vs .and_then() 有啥区别?

方法用法说明示例
.map()对值做处理,结果仍在容器内`Some(2).map(
.and_then()处理后返回另一个容器(嵌套)`Some(2).and_then(

.map() 相当于你“只动里面的值”,.and_then() 是你“根据值决定接下去是否继续”。


🔁 第七部分:组合多个操作 - 用 Monad 串业务逻辑

fn parse_id(s: &str) -> Option<i32> {s.parse().ok()
}fn check_id(id: i32) -> Option<i32> {if id > 0 { Some(id) } else { None }
}fn query_user(id: i32) -> Option<String> {Some(format!("用户{}", id))
}let user = Some("42").and_then(parse_id).and_then(check_id).and_then(query_user);

用人话解释:

如果字符串能成功转成数字、这个数字大于 0、还能找到用户,就返回用户名;否则中途停止。

这就是典型的:组合多个失败可能的操作


🧾 第八部分:总结表格

类型类型构造器unit函数bind函数上下文解释
OptionSome(x)Some(x)and_then可能没有值
ResultOk(x)/Err(e)Ok(x)and_then成功/失败状态
Futureasync { x }asyncawait / then值尚未获得

✅ 结语

掌握 Monad 不是为了炫技,而是为了安全、优雅、高复用地处理流程和异常

如果你能理解这三句话:

  • 我可以从值开始(左单位律)
  • 我可以随时停下不处理(右单位律)
  • 我可以拆写也能合写(结合律)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/77435.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PL/SQL登录慢,程序连接Oracle 提示无法连接或无监听

PL/SQL登录慢&#xff0c;程序连接Oracle 提示无法连接或无监听 错误提示&#xff1a;ORA-12541: TNS: 无监听程序 的解决办法&#xff0c; 现象&#xff1a;PL/SQL登录慢&#xff0c;程序连接Oracle 提示无法连接或无监听 监听已经正常开起&#xff0c;但还是PL/SQL登录慢或…

Windows10,11账户管理,修改密码,创建帐户...

在这里&#xff0c;我们使用微软操作系统的一款工具:netplwiz 它可以非常便捷的管理用户账户. 一:修改密码(无需现在密码) 01修改注册表 运行命令&#xff1a;regedit 在地址栏输入&#xff1a; HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Passwor…

电脑 BIOS 操作指南(Computer BIOS Operation Guide)

电脑 BIOS 操作指南 电脑的BIOS界面&#xff08;应为“BIOS”&#xff09;是一个固件界面&#xff0c;允许用户配置电脑的硬件设置。 进入BIOS后&#xff0c;你可以进行多种设置&#xff0c;具体包括&#xff1a; 1.启动配置 启动顺序&#xff1a;设置从哪个设备启动&#x…

iOS 冷启动时间监控:启动起点有哪些选择?

⏱️ iOS 冷启动时间监控&#xff1a;启动起点有哪些选择&#xff1f; 作者&#xff1a;侯仕奇 来源&#xff1a;sqi.io 在监控 iOS 冷启动性能时&#xff0c;一个关键问题是&#xff1a;如何精确记录 App 冷启动的开始时间&#xff1f; 本文将对不同的“冷启动起点”监控方式…

onlyoffice关闭JWT后依然报错如何解决?

onlyoffice关闭JWT后依然报错如何解决&#xff1f; 一、部署方式 我是以docker方式部署的&#xff0c;直接通过环境变量禁用了JWT&#xff0c;命令如下&#xff1a; docker run -d \--name onlyoffice-no-jwt \--restartalways \-p 8069:80 \-e JWT_ENABLEDfalse \onlyoffic…

rk3588 驱动开发(一)字符设备开发

3.字符设备驱动开发 3.1 什么是字符设备驱动 字符设备&#xff1a;就是一个个字节&#xff0c;按照字节流进行读写操作的设备&#xff0c;读写是按照先后顺序的。 举例子&#xff1a;IIC 按键 LED SPI LCD 等 Linux 应用程序调用驱动程序流程&#xff1a; Linux中驱动加载成功…

设计模式 --- 外观模式

外观模式是一种结构型设计模式&#xff0c;为复杂子系统提供​​统一的高层接口​​&#xff0c;通过定义一个外观类来​​简化客户端与子系统的交互​​&#xff0c;降低系统耦合度。这种模式隐藏了子系统的复杂性&#xff0c;将客户端与子系统的实现细节隔离开来&#xff0c;…

我的gittee仓库

日常代码: 日常代码提交https://gitee.com/xinxin-pingping/daily-code 有需要的宝子们可自行读取。

微服务调用中的“大对象陷阱”:CPU飙高问题解析与优化

背景 对几十万条用户历史存量数据写入&#xff0c;且存在大对象的基础上。kafka消费进行消费写mysql超时。导致上游服务调用时异常&#xff0c;CPU飙高异常。 大对象解释 大对象的定义与危害 1. 什么是大对象&#xff1f; JVM 内存分配机制&#xff1a;Java 中对象优先分配…

代码随想录算法训练营day6(字符串)

华子目录 反转字符串思路 反转字符串II思路 替换数字思路 反转字符串 https://leetcode.cn/problems/reverse-string/ 思路 使用双指针&#xff0c;初始化时&#xff0c;left指向下标0的位置&#xff0c;right指向最后一个元素的下标当while left<right时&#xff0c;交换…

Oracle 19c新特性:OCP认证考试与职业跃迁的关键?

在数字化转型的浪潮中&#xff0c;Oracle 19c作为数据库领域的旗舰版本&#xff0c;不仅承载着技术革新的使命&#xff0c;更成为IT从业者职业进阶的“黄金跳板”。无论是企业级应用的高可用性需求&#xff0c;还是云原生架构的快速迭代&#xff0c;Oracle 19c的智能化与多模型…

【MySQL数据库入门到精通】

文章目录 一、SQL分类二、DDL-数据库操作1.查询2.创建数据库3.删除数据库4.使用数据库 三、DDL-表操作1.查询 一、SQL分类 根据功能主要分为DDL DML DQL DCL DDL:Date Definition Language数据定义语言&#xff1a;定义数据库&#xff0c;表和字段 DML:Date Manipulatin Lan…

MCP服务端开发

MCP(Memory, Context, Planning)是一种增强AI系统认知能力的框架,通过整合记忆管理、上下文理解和规划能力,可以显著提升AI系统的表现。下面我将为您开发一个完整的MCP服务端。 概述 我们将使用Python开发一个基于FastAPI的MCP服务端,包含以下核心组件: Memory Manager…

前端:uniapp中uni.pageScrollTo方法与元素的overflow-y:auto之间的关联

在uniapp中&#xff0c;uni.pageScrollTo方法与元素的overflow-y:auto属性之间存在以下关联和差异&#xff1a; 一、功能定位差异 ‌uni.pageScrollTo‌ 属于‌页面级滚动控制‌&#xff0c;作用于整个页面容器‌34。要求页面内容高度必须超过屏幕高度&#xff0c;且由根元素下…

基础知识-指针

1、指针的基本概念 1.1 什么是指针 1.1.1 指针的定义 指针是一种特殊的变量&#xff0c;与普通变量存储具体数据不同&#xff0c;它存储的是内存地址。在计算机程序运行时&#xff0c;数据都被存放在内存中&#xff0c;而指针就像是指向这些数据存放位置的 “路标”。通过指针…

VS远程Linux_CMake项目搭建

VS远程Linux CMake项目搭建 准备工作 远程计算机上安装 gcc: 一个开源的编译器集合, GCC支持多种编程语言的编译&#xff0c;包括C、C、Objective-C、Fortran、Ada、Go、D和Javagdb: GDB&#xff08;GNU Debugger&#xff09;是一个功能强大的调试工具&#xff0c;主要用于调…

替代升级VMware | 云轴科技ZStack构建山西证券一云多芯云平台

通过云轴科技ZStack Cloud云平台&#xff0c;山西证券打造了敏捷部署、简单运维的云平台&#xff0c;不仅兼容x86、海光、鲲鹏三种异构服务器实现一云多芯&#xff0c;还通过云平台虚拟化纳管模块纳管原有VMware虚拟化资源&#xff0c;并对接第三方集中式存储&#xff0c;在保护…

MATLAB - 模型预测控制器(MPC)的稳定性和鲁棒性问题

系列文章目录 目录 系列文章目录 前言 一、被控对象模型 二、初始控制器设计 三、改进初始设计 五、查看软约束 七、参考 前言 您可以检查模型预测控制器设计是否存在潜在的稳定性和鲁棒性问题。具体操作如下 在命令行中&#xff0c;使用审查功能。在 MPC Designer 中&a…

《GPT-4.1深度解析:AI进化新标杆,如何重塑行业未来?》

一、GPT-4.1:AI 领域的 “全能战士” 降临 1.1 发布背景与战略意义 在 OpenAI 的技术迭代版图中,GPT-4.1 被赋予了 “承前启后” 的关键角色。它不仅是 GPT-4o 的全面升级版,更被视为向 GPT-5 过渡的重要桥梁。2025 年 4 月 15 日的发布会上,OpenAI 宣布 GPT-4.1 系列模型…

MySQL+Redis实战教程:从Docker安装部署到自动化备份与数据恢复20250418

MySQLRedis实战教程&#xff1a;从Docker安装部署到自动化备份与数据恢复 一、前言 在企业应用中&#xff0c;对MySQL和Redis运维的要求越来越高&#xff1a; 不能仅是启动就算部署运行稳定、隔离、访问控制、备份恢复、安全可靠&#xff0c;才是 企业级的基本功能 本文将手…