clojure - 这个 map 解构并不像我期望的那样工作。我究竟做错了什么?

标签 clojure

作为一个例子,希望能比我用语言更好地说明事情:

(let [{:keys [a b c] :or {a 1 b 2 c 3} :as m} {}]
  (println a b c) ; => works as expected, output is: 1 2 3
  (println m) ; => this doesn't work, output is: {}
)

我希望第二个 println 的输出是包含默认值的映射,就好像被合并推到那里一样(即 {:a 1 :b 2 :c 3})。

相反,在 m 被绑定(bind)之后,看起来 vars 正在被召唤和​​ or'd。为什么 :as 不受 : 或 :keys 的影响?

我的心智模型有什么问题?我应该如何看待这个?

编辑:
我想出了它是如何工作的,就像我在上面展示的那样(尽管感谢链接)。从那以后,我也通读了 clojure.core/destructure 的源代码,现在确切地知道它在做什么。我的问题真的是“为什么?”

在 Clojure 中,事情以它们的方式运行似乎总是有原因的。他们在这里做什么?

很抱歉,问题是“解构如何与 :as 和 :or 一起工作”。

最佳答案

我不是有钱人,所以显然我没有选择它的工作方式,但我能想到当前行为比您预期的行为更好的几个原因。

  1. 更快。 Clojure 的许多低级核心功能一直在您的程序中使用,为了获得可接受的性能,它们的优化更多是为了速度而不是优雅。当然,如果这是一个正确性的问题,那就另当别论了,但是这里有两种听起来很合理的 :as 行为方式,所以选择更快的方式似乎是个好计划。至于为什么它更快,我认为这很明显,但是:我们已经有一个指向原始 map 的指针,我们可以重用它。要使用“修改后的” map ,我们必须使用一堆 assoc 调用来构建它。

  2. 如果 :as 不给你原始对象,你怎么可能得到原始对象呢?你不能,真的,对吧?而如果 :as 将原始对象返回给您,您可以根据需要轻松构建修改后的版本。因此,一种行为会为您留下更多选择。

关于clojure - 这个 map 解构并不像我期望的那样工作。我究竟做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28593282/

相关文章:

Clojure 宏 : Passing filtered map and arity to other macro based on condition

json - 如何选择Clojure JSON库

Clojure 秘书 - URL 更改时的调度

clojure - 在 Clojure (.clj) 脚本中导入 .jar (vaadin-6.4.8.jar) 文件

clojure - clojure 代码示例中的这个函数定义有什么作用?

clojure - 简单的惰性序列上的doseq耗尽了堆空间

clojure - Lein 使用协议(protocol)编译项目

Clojure - 评估高阶函数的返回函数

Clojure 交易策略

clojure - 从 map 注册 clojure.specs