Clojure map中函数调用顺序是否保证运行时按定义顺序执行?
问题1 实现调用顺序的方案
你可以通过let绑定强制指定执行顺序,let的绑定表达式严格按照书写的从上到下顺序执行,不存在歧义,改造后的代码如下:
(defn process-request [request] (if (not (db/empty?)) (let [violations (:violations (process-violations request)) person (db/get-person!)] {:person person :violations violations}) {:person {} :violations ["no-person"]}))
这种写法会先执行process-violations拿到违规结果,再执行db/get-person!获取人员数据,完全符合你的调用顺序要求。
问题2 字面量map的求值顺序说明
Clojure的字面量map的求值顺序不能作为可靠的执行顺序保证:
- 当map的键值对数量≤8时,默认生成有序的
PersistentArrayMap,此时会按照你书写的从左到右顺序求值值表达式 - 当map的键值对数量>8时,会自动转换为无序的
PersistentHashMap,此时值表达式的求值顺序没有明确保证 - 即使是小容量的有序map,依赖字面量顺序的写法也属于隐含逻辑,可读性极差,后续维护很容易因为调整键的顺序引入隐性bug
因此绝对不要依赖map的键顺序控制函数调用的执行顺序。
内容的提问来源于stack exchange,提问作者brenobarreto
相关产品推荐
相关产品推荐

