作为一个例子,希望能够比言语更好地陈述事情:
(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的输出是包含默认值的地图,好像在那里通过merge推送(即{:a 1:b 2:c 3})。
相反,在绑定m之后看起来像变形和变形。为什么:因为不受以下因素的影响:或者像:键呢?
我的心理模型出了什么问题?我该怎么看?
修改
我想出它是如何工作的,因为我认为我已经在上面展示了(尽管感谢链接)。我也读过clojure.core / destructure的来源,现在确切知道它在做什么。我的问题真的是'为什么?'
在Clojure中,似乎总有一种理由可以像他们一样工作。他们在这里干什么?
我很抱歉这个问题出现了'解构如何与:as和:或'。
答案 0 :(得分:4)
我不富有,所以很明显我没有选择这是如何运作的,但我可以想到一些原因,目前的行为比你预期的行为更好。
速度更快。很多Clojure的低级核心功能在程序中始终使用,并且为了获得可接受的性能,它们的优化速度优于优雅。当然,如果这是一个正确的问题,它将是一个不同的故事,但这里有两种合理的方式:as
表现,所以选择更快的方式似乎是一个好的计划。至于为什么它更快,我认为这是显而易见的,但是:我们已经有一个指向原始地图的指针,我们可以重复使用它。要使用"修改过的" map,我们必须使用一堆assoc调用来构建它。
如果:as
没有给你回原始对象,你怎么可能得到原始对象?你不能,真的,对吗?如果:as
为您提供原始对象,则可以根据需要轻松构建修改后的版本。因此,一种行为会为您留下更多选择。
答案 1 :(得分:3)
根据Special Forms,:as
和:or
在init-expr
方面都是独立的:
此外,可选地,绑定表单中的
:as
键后跟符号将导致该符号绑定到整个init-expr 。也可选择,绑定表单中的:or
键跟随另一个地图可用于为部分或全部键提供默认值(如果在init中找不到它们) -expr 强>
答案 2 :(得分:3)
正如您所发现的,解构中的:or
键不会影响:as
。 :as
将捕获原始输入,无论默认值的应用还是通过&
等封装其余元素。
同样可选地,a:或绑定表单中的键后跟另一个键 map可用于为某些或所有键提供默认值 如果在init-expr中找不到它们
...
最后,也是可选的,:后跟一个符号会导致这种情况 要绑定到整个init-expr的符号