You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clojure中def内的'@foo类为何是Cons而非PersistentList?

原因说明

前置规则

  • Clojure 读取器会优先处理前缀读取器宏:' 是 quote 宏的简写,@ 是 deref 宏的简写,因此 '@foo 会被等价展开为 '(deref foo),即被quote包裹的两元素列表 (deref foo)。
  • Clojure 编译器默认开启常量内存优化,对编译期可确定的常量值,会优先用开销更低的结构存储。

两类场景的差异

  1. 直接执行 (class '@foo) 时,'@foo 展开的两元素列表是函数调用的临时参数,不属于需要长期存储的编译期常量,因此会用通用的 clojure.lang.PersistentList 结构存储,返回结果符合预期。
  2. 执行 (def x '@foo) 时,'@foo 展开的两元素列表是def绑定的全局常量值,会触发编译器优化:长度为2的短列表会被转换为更轻量的 clojure.lang.Cons 结构存储(Cons仅存储当前元素和尾部指针,内存开销远低于PersistentList),因此查询x的类型会得到Cons。

补充说明

该行为并非 '@foo 特有,所有长度为2的被quote字面量列表作为def的绑定值时都会触发该优化,你可以执行下面的代码验证:

(def y '(a b))
(class y)
;; 同样返回 clojure.lang.Cons

你之前测试其他形式没有触发,大概率是因为其他quote形式展开后的长度大于2,不属于优化覆盖范围。

内容的提问来源于stack exchange,提问作者Rafał Dowgird

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:48:02