“写笔记”支持四种格式——Word 文档、Excel 表格、Markdown、纯文本,起稿或二次编辑时都能随时切换,同一篇笔记想用哪种形态来记,都由你说了算。
md、txt、csv、json 这类纯文本则原样载入,不做多余加工。拿一张现成的表倒进来、改几笔、再导出去,等于白用一台免费的格式转换器。
要带走就在右上角点“下载”,可导出 PDF、Word、Markdown、Excel、TXT 等格式;列表卡片“⋯”菜单里,也有同样的下载入口。
在“工具”页点“+ 上传工具”即可发布:填好名称与链接,再用 Markdown 把使用方法写清楚——能解决什么问题、怎么装、怎么用,比堆介绍实在。
要分发安装包就一并上传压缩包(ZIP、RAR、7Z、TAR.GZ,最大 35MB),别人在详情页一键下载;只放链接不带附件也可以。
工具按大家的收藏热度排序,好用的自然会被顶上来。发布后可在详情页或卡片菜单里编辑、下架。
写笔记时勾上“隐藏”,这篇就只存在于你自己的账号里:不进列表、不进搜索、不上首页精选,也不会出现在任何公开的页面,链接发给别人同样打不开。
适合放密码、草稿、日记这类只给自己看的内容;想公开,去“发布”打开它,把“隐藏”的勾去掉再保存,之后编辑会默认保持原状态,不会悄悄变回公开。
你的内容会同时保存在多个副本上,系统定期做备份与完整性校验,再配合异地容灾机制:就算某台机器出问题,数据也不会丢,可以长期放心存放;特别重要的资料,仍建议你另外再留一份备份。
全站跑在容器化、模块化的现代架构上,更新、部署、回滚都很快,扩展性和稳定性都按长期运营的标准来设计(Built for reliability, designed to scale)。
这个网站最早只是一个人的笔记仓库,后来慢慢长成现在的知识中枢。设计上很克制——没有广告、没有追踪、没有推荐算法,只是干干净净地存放一些东西;既然做好了,就公开出来,万一有人用得上呢。
不做大而全,不做平台梦,保持简单、保持克制、保持好奇。所有内容都由用户贡献、由用户维护:不会突然冒出付费墙,不会在角落塞广告位,也不会把你的数据卖给第三方。
产品会持续迭代,站内日志页记录着每一次改动,改了什么都有迹可循;想了解这个站是怎么一步步走到今天的,翻翻日志就能看到来龙去脉。
如果在这里看到涉嫌违规的内容,点对应卡片右侧的“举报”按钮就能提交,我们会尽快核实处理;也谢谢你花一点时间,一起把这里维护干净。
Clojure 1.13 新特性深度解析:检查键(Checked Keys)与映射解构增强
Clojure 1.13 引入检查键机制,在解构时强制校验必需键,提升代码健壮性。
概述
Clojure 1.13.0-alpha1 于 2026 年 7 月 2 日发布,由 Alex Miller 主导。本次更新最核心的特性是 检查键(Checked Keys) 机制,它允许开发者在映射(map)解构时,对必需键进行强制绑定校验,若键缺失则抛出异常。此外,还包含一些性能优化、规范定义和语法限制调整。
检查键(Checked Keys)详解
背景:解构时的痛点
在 Clojure 中,映射解构(map destructuring)是一种常用模式,用于从映射中提取键值对并绑定到局部变量。例如:
clojure
(let [{:keys [name age]} {:name "Alice" :age 30}]
(println name age)) ;; 输出 Alice 30
然而,当映射中缺少某个键时,例如 {:name "Alice"} 缺少 :age,age 会被绑定为 nil,而不会报错。这可能导致后续代码在不知情的情况下使用 nil,引发难以调试的 bug。
检查键语法:! 后缀
Clojure 1.13 引入了三个新的解构指令变体,通过在原有指令后添加感叹号 ! 来启用强制校验:
:keys!:检查键名对应的值是否缺失:syms!:检查符号键对应的值是否缺失:strs!:检查字符串键对应的值是否缺失
如果被标记的键在映射中不存在,解构时会立即抛出异常,而不是静默返回 nil。
示例:
clojure
;; 正常情况:键都存在,正常工作
(let [{:keys! [name age]} {:name "Alice" :age 30}]
(println name age)) ;; 输出 Alice 30
;; 键缺失:抛出异常
(let [{:keys! [name age]} {:name "Alice"}]
(println name age)) ;; 抛出异常:Missing required key :age
使用 & 进行文档或检查用途的键声明
除了强制绑定,Clojure 1.13 还允许在所有解构指令(包括 :keys、:syms、:strs 以及它们的 ! 变体)中使用 & 符号来声明一些键,这些键不会被绑定,仅用于文档或检查目的。
示例:
clojure
(let [{:keys [name & age]} {:name "Alice" :age 30}]
(println name)) ;; 输出 Alice,age 不会被绑定
这里 age 出现在 & 之后,它不会成为局部变量,但可以用于说明该映射期望包含哪些字段,或者配合规范(spec)进行验证。
相关 JIRA 工单
- CLJ-2961:检查键的核心功能
- CLJ-2960:为检查键定义规范(spec)
- CLJ-2949:
req!——get的变体,在键不存在时报错(底层支持) - CLJ-2954:禁止在
let/loop/let*中使用&作为局部绑定名(避免歧义)
其他重要变更
1. PersistentArrayMap 扩容阈值提升
在 Clojure 1.12.5 及之前版本中,仅包含关键字键的 PersistentArrayMap(PAM),当键数量超过 8 个时,会自动转换为 PersistentHashMap(PHM)。
变更: 在 1.13 中,这个阈值从 8 提升到 64。
原因与优势:
- PAM 的线性扫描(identity scan)在较小规模下比 PHM 的哈希查找更高效。
- 更大的阈值意味着更多小映射保持为 PAM 形态,减少了哈希计算开销。
- 更多的调用点(call sites)保持单态(monomorphic),有利于 JIT 编译器(如 C2)进行内联和优化。
2. 移除静态初始化常量的 ACC_FINAL 标志
这是一个为未来 Java 字节码基线升级做的准备。新的 JVM 验证器(verifier)对 ACC_FINAL 的使用有更严格的检查,提前移除可以避免后续兼容性问题。
3. 运行时与测试依赖更新
所有运行时和测试依赖已更新到最新版本,确保安全性与稳定性。
如何体验
通过 deps.edn 添加依赖
在项目的 deps.edn 文件中添加:
clojure
{:deps {org.clojure/clojure {:mvn/version "1.13.0-alpha1"}}}
使用 Clojure CLI 启动 REPL
bash
clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.13.0-alpha1"}}}'
深度思考与最佳实践
为什么需要检查键?
在函数式编程中,数据通常以映射形式传递。传统的解构方式允许缺失键,这虽然灵活,但也增加了运行时错误的隐蔽性。检查键机制借鉴了 Typed Clojure 或 Schema 等库的强制校验思想,将错误提前暴露,符合“快速失败”(fail-fast)原则。
与规范(spec)的关系
Clojure 1.13 同时为检查键提供了规范定义(CLJ-2960),这意味着你可以通过 clojure.spec.alpha 对解构过程中的键进行更细粒度的验证,例如类型检查或值范围约束。
何时使用 :keys! vs :keys?
- 使用
:keys!:当某个键是业务逻辑的必要输入,缺失意味着程序无法正确运行时。例如,用户 ID、请求参数中的必填字段。 - 使用
:keys:当键是可选的,缺失时应有默认值或合理降级行为。
对性能的影响
检查键仅在解构时执行一次 contains? 检查,性能开销极低。对于大多数应用,这种微小的代价换来的代码健壮性是完全值得的。
总结
Clojure 1.13.0-alpha1 通过检查键机制填补了语言在解构安全性上的一个空白。它让开发者能够显式地声明必需键,避免因 nil 传播导致的隐性错误。同时,PAM 扩容阈值的提升和底层字节码调整,展现了 Clojure 团队在保持语言简洁性的同时,持续优化性能与兼容性的努力。
对于正在使用 Clojure 构建生产系统的团队,建议在 alpha 阶段即开始测试检查键特性,以便在正式版发布时平滑迁移。
原文链接:https://clojure.org/news/2026/07/02/clojure-1-13-alpha1