Roc 语言 Dict.update 详解:以 Err(Missing) 返回值为例实现键的删除语义
【免费下载链接】rocA fast, friendly, functional language.项目地址https://gitcode.com/GitHub_Trending/ro/roc点击查看免费下载本文以 Roc 仓库中的 REPL 快照文档 dict_update_remove.md 为核心骨架结合其兄弟快照与内置模块源码系统讲解Dict.update的完整语义它如何通过一个alter函数同时覆盖插入、修改、删除三种操作并重点剖析当 alter 函数返回Err(Missing)时键会被移除这一关键行为。读完本文你将掌握Dict.update的调用约定、底层哈希表实现原理以及如何用一次查找高效地完成条件性增删改。一、快照文档解读一条 REPL 测试背后的三种能力仓库中的test/snapshots/repl/目录存放了一批 REPL 快照测试每个.md文件都是一个独立的端到端用例格式统一为四段段落作用META以 ini 格式记录用例描述与类型typerepl表示这是 REPL 交互式测试SOURCE输入到 REPL 的 Roc 表达式以»提示符开头OUTPUT期望的 REPL 输出多个输出之间用---分隔PROBLEMS已知问题列表NIL表示当前无问题、测试应通过dict_update_remove.md 完整内容如下# META ~~~ini descriptionDict.update removes the key when the alter function returns Err(Missing) typerepl ~~~ # SOURCE ~~~roc » Dict.update(Dict.single(k, 10), k, |_| Err(Missing)).len() ~~~ # OUTPUT 0 # PROBLEMS NIL这条测试表达的含义非常精确对只含一个键值对(k, 10)的字典用alter |_| Err(Missing)调用Dict.update最终字典的len()为0——键k被删除了。快照中PROBLEMS为NIL说明这是当前已实现且被验证通过的稳定行为而非待办缺陷。二、Dict.update 的完整调用约定要理解上面这条测试必须先看懂Dict.update的签名与约定。其定义位于内置模块 src/build/roc/Builtin.rocupdate : Dict(k, v), k, (Try(v, [Missing]) - Try(v, [Missing])) - Dict(k, v) where [k.is_eq : k, k - Bool, k.to_hash : k, Hasher - Hasher]它接收三个参数原字典、目标键、以及一个alter函数返回处理后的新字典。关键约定有两条alter 函数收到的输入若键当前存在于字典中传入Ok(value)若键不存在传入Err(Missing)。alter 函数的返回值决定动作返回Ok(new_value)键不存在则插入键已存在则更新返回Err(Missing)键已存在则删除该键键原本就不存在则保持原状字典不变。本文主角 dict_update_remove.md 验证的正是第二条中返回Err(Missing)删除已存在键的分支。与之配套的两个兄弟快照分别验证了另外两个分支dict_update_insert.md对空字典调用Dict.update(Dict.empty(), a, |_| Ok(42))随后get(a)返回Ok(42.0)证明Err(Missing)输入 Ok(value)返回 插入dict_update_modify.md对已有键k调用Dict.update(Dict.single(k, 10), k, |_| Ok(99))随后get(k)返回Ok(99.0)证明Ok(value)输入 Ok(value)返回 更新。三个快照合在一起恰好覆盖了alter函数输入输出四种组合中的三种另外一种是键缺失 返回Err(Missing)结果是不改变字典属于平凡分支。三、源码级剖析一次查找完成三种动作Dict.update之所以比先Dict.get再Dict.insert更高效是因为它在底层实现中只做一次哈希查找并在匹配结果上直接分发到不同的数据操作。源码实现如下src/build/roc/Builtin.rocupdate |dict, key, alter| match dict { HashMap(data) match dict_find(data, key) { Found(found) match alter(Try.Ok(found.value)) { Try.Ok(new_value) { entries list_set_unsafe(data.entries, found.entry_index, (key, new_value)) HashMap({ entries, buckets: data.buckets, max_entries_before_grow: data.max_entries_before_grow, shifts: data.shifts }) } Try.Err(Missing) HashMap(dict_remove_bucket_data(data, found.bucket_index)) } Missing(missing) match alter(Try.Err(Missing)) { Try.Ok(new_value) HashMap(dict_insert_absent_data(data, missing, key, new_value)) Try.Err(Missing) dict } } }执行流程可以拆成清晰的四步一次查找dict_find(data, key)在哈希表中定位键得到Found已存在含 value 与索引或Missing不存在含可插入位置信息。无论后续走哪个分支查找都只发生这一次。键已存在 Ok(new_value)→ 原地更新用list_set_unsafe把 entries 数组中该键对应的值替换为新值其余字段原样保留构造新HashMap。这正是 dict_update_modify.md 验证的路径。键已存在 Err(Missing)→ 删除调用dict_remove_bucket_data(data, found.bucket_index)从桶数组中移除该键对应的槽位返回的新字典长度减一。这就是 dict_update_remove.md 中.len()输出0的直接原因。键不存在 Ok(new_value)→ 插入调用dict_insert_absent_data(data, missing, key, new_value)在dict_find返回的空位处写入新键值对键不存在 Err(Missing)→ 原样返回dict不产生任何分配。值得注意的是步骤 3 与 4 都复用了查找阶段获得的定位信息bucket_index/missing因此整个update的哈希计算与探测成本是单次级别的这正是文档注释所强调的比Dict.get之后再Dict.insert更高效Builtin.roc。从实现细节还能推断出字典的底层表示Dict内部是HashMap(data)其中data由entries键值对条目数组、buckets桶数组、max_entries_before_grow扩容阈值与shifts哈希移位参数四个字段构成是一个典型的开放寻址哈希表结构。dict_find、dict_insert_absent_data、dict_remove_bucket_data这些辅助函数就是围绕该结构工作的底层原语。四、与其他删除类操作的对比Dict.update并非唯一的删除途径仓库中还有专用于删除的函数便于在不同场景下选择Dict.remove直接按键删除无需 alter 函数。快照 dict_remove.md 展示了其行为——删除已存在的键后len()为1、contains(a)为False对不存在的键调用remove(missing)则字典保持不变len()仍为1。语义等价于Dict.update中alter 恒返回Err(Missing)的特例但书写更简洁。Dict.remove_all接收第二个字典删除第一个字典中键与第二个字典键相同的所有键值对集合差语义源码见 Builtin.roc快照 dict_remove_all.md 有对应测试。三者的取舍可以概括为纯删除用Dict.remove批量按集合差删除用Dict.remove_all而根据当前值决定是更新还是删除这种条件化需求则必须用Dict.update——因为它把读旧值 决策 写新值合并为一次查找避免了两次哈希访问之间的竞态窗口在纯函数式、不可变数据结构语境下则体现为时间与分配成本的节省。五、实战场景与典型模式Dict.update最典型的用法是计数器的存在性判断——根据键是否存在来决定插入初始值还是累加。内置文档示例Builtin.roc给出了一个等价的可运行模式alter |possible_value| match possible_value { Err(Missing) Ok(Bool.False) # 键不存在插入 False Ok(value) if value Err(Missing) else Ok(Bool.True) # 键存在按值决定删或更新 }而 dict_update_remove.md 的快照则揭示了一个更简洁的惯用法当需要命中即删除、未命中即忽略时可以直接传入恒返回Err(Missing)的 lambda|_| Err(Missing)配合Dict.update一次调用完成条件删除效果等价于Dict.remove但统一在同一个更新心智模型下。实际项目中常将三者组合使用例如# 键存在则累加不存在则初始化为 1计数器惯用法 Dict.update(counts, roc, |v| Ok(match v { Ok(n) n 1 Err(Missing) 1 })) # 键存在则删除不存在则原样保留幂等删除 Dict.update(counts, roc, |_| Err(Missing))六、小结一条快照、三种语义、一次查找围绕 dict_update_remove.md 这一条 REPL 快照可以完整还原 Roc 中Dict.update的设计全貌契约清晰alter以Try(v, [Missing])收尾以Try(v, [Missing])返回四种输入输出组合对应更新 / 删除 / 插入 / 不变四种结果实现高效底层只做一次dict_find查找再利用查到的索引直接更新条目、移除桶位或插入新数据Builtin.roc验证完备仓库通过 dict_update_remove.md、dict_update_insert.md、dict_update_modify.md 三份快照分别锁定了删除、插入、更新三种行为PROBLEMS均为NIL可作为可靠的参考用例继续研读。赞分享【免费下载链接】rocA fast, friendly, functional language.项目地址https://gitcode.com/GitHub_Trending/ro/roc点击查看免费下载相关推荐Roc 语言 REPL 数值解析失败路径详解以 F64.from_str 的 Err(BadNumStr) 快照测试为例Roc 语言 REPL 数值解析失败路径详解以 F64.from_str 的 Err BadNumStr 快照测试为例 F64.from_str 是 RocPuter 键值存储删除操作全解puter.kv.del() 的用法、返回值语义与源码实现Puter 键值存储删除操作全解 puter.kv.del 的用法、返回值语义与源码实现 puter.kv.del 是 Puter 开源云端操作系统的官方 J后端前端云原生3个技巧让Layerdivider成为你的AI分层魔法师3个技巧让Layerdivider成为你的AI分层魔法师 你是否曾面对一张精美的插画却苦于无法轻松分离其中的元素Layerdivider正是那个能将复杂图像创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

MAX30102心率检测实战:从I2C驱动到PPG信号处理

MAX30102心率检测实战:从I2C驱动到PPG信号处理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 22:11:52 阅读更多 →
pi 编程智能体 CLI 实战:agent loop 原理、LLM API 配置与 TUI 避坑指南

pi 编程智能体 CLI 实战:agent loop 原理、LLM API 配置与 TUI 避坑指南

1. 从一个字母说起:pi 到底是什么第一次看到 "pi" 这个项目标题,很多人脑子里蹦出来的可能是圆周率,或者某个数学库。但如果你最近在开发者社区里泡过,尤其是关注 AI 编程工具这条线,就会知道这个 "pi&…

2026/9/22 20:40:39 阅读更多 →
Cherry Studio 升级 @ai-sdk/deepseek 至 2.0.57:修复 DeepSeek 视觉模型图片输入被丢弃的问题

Cherry Studio 升级 @ai-sdk/deepseek 至 2.0.57:修复 DeepSeek 视觉模型图片输入被丢弃的问题

Cherry Studio 升级 ai-sdk/deepseek 至 2.0.57:修复 DeepSeek 视觉模型图片输入被丢弃的问题 【免费下载链接】cherry-studio 🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端 项目地址: https://gitcode.com/CherryHQ/cherry-studio 导…

2026/9/22 12:44:49 阅读更多 →

最新新闻

确定性网络白皮书拆解:FlexE、TSN、DetNet 技术选型与落地避坑指南

确定性网络白皮书拆解:FlexE、TSN、DetNet 技术选型与落地避坑指南

简介:《未来网络白皮书:确定性网络技术体系》由网络通信与安全紫金山实验室联合华为、北京邮电大学等单位编写,面向网络通信研究者、工业互联网从业者及高校师生,系统解答传统“尽力而为”互联网难以满足智能制造、远程医疗、自动…

2026/9/23 16:23:19 阅读更多 →
Goemon64Recomp版本发布状态解析:静态重编译工程的产品化之路

Goemon64Recomp版本发布状态解析:静态重编译工程的产品化之路

1. 项目背景与核心定位拆解1.1 这个项目到底在做什么Goemon64Recomp 是一个围绕经典 N64 平台游戏《大盗五右卫门》系列(Mystical Ninja 系列)进行静态重编译(Static Recompilation)的工程。它的核心目标不是模拟器式的逐指令解释…

2026/9/23 16:23:19 阅读更多 →
基于Python的BERT情感分析实战:从微调训练到GUI部署

基于Python的BERT情感分析实战:从微调训练到GUI部署

简介:基于Python实现的BERT情感分析模型,面向自然语言处理课程设计与情感分析入门者,提供从语料训练到测试验证的完整工程。资源以正向、无情感、负向三分类语料训练模型,训练语料超过1万条,迭代3次后在3000余条测试集…

2026/9/23 16:23:19 阅读更多 →
BERT微调实现多标签文本分类的Keras实战指南

BERT微调实现多标签文本分类的Keras实战指南

简介:基于Keras与Keras-bert的文本多标签分类项目包,面向自然语言处理实战场景,通过微调BERT完成多标签分类,并以2020语言与智能技术竞赛事件抽取任务作为数据样例,适合需要快速落地预训练模型的开发者和研究者。压缩包…

2026/9/23 16:23:19 阅读更多 →
BERT+BiLSTM+CRF中文命名实体识别实战:从数据预处理到模型部署

BERT+BiLSTM+CRF中文命名实体识别实战:从数据预处理到模型部署

简介:面向中文命名实体识别(NER)的Python项目源码,以BERTBiLSTMCRF为核心框架,同时提供BiLSTMCRF、IDCNNCRF等多种对比实现,覆盖数据预处理、模型训练与评估全流程。压缩包共58个文件,以16个Pyt…

2026/9/23 16:23:19 阅读更多 →
高中数学竞赛题实战项目:3步搞定API变更

高中数学竞赛题实战项目:3步搞定API变更

高中数学竞赛题实战项目:3步搞定API变更 版本升级后 API 全变了,代码直接报错?别慌。 在重构这个【高中数学竞赛题】自动判题系统时,我遇到了同样的地狱级现场。 旧版解析库突然废弃了核心接口,导致整个 实战项目 无法运行。…

2026/9/23 16:22:16 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →