Clojure 这张地图的解构不是';我工作得不太好';我希望如此。我做错了什么?

Clojure 这张地图的解构不是';我工作得不太好';我希望如此。我做错了什么?,clojure,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的输出是包含默认值的映射,就好像是通过merge(即{:a1:b2:c3})插入

作为一个例子,我希望它比我所能用语言表达的要好得多:

(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(即{:a1:b2:c3})插入其中一样

相反,它看起来像是变戏法,或者在m被绑定后变戏法。为什么:as不受:或类似:keys影响

我的思维模式有什么问题?我应该怎么看这个

编辑:
我知道它是如何工作的,正如我在上面所说的那样(尽管还是要感谢链接)。此后,我还通读了clojure.core/destructure的源代码,现在完全知道它在做什么。我的问题是‘为什么?’

在Clojure中,事情按照他们的方式运行似乎总是有原因的。他们在这里干什么

很抱歉,这个问题被理解为“分解如何与:as和:or一起工作”。

根据,
:as和
:or
init expr
方面各自独立:

此外,可选地,绑定形式中的
:as
键后跟符号将导致该符号绑定到整个init expr。另外,如果在init expr中找不到部分或全部键,则可以选择使用另一个映射后的绑定形式的
:或
键来提供这些键的默认值


正如您所发现的,解构中的
:或
键不会影响
:As
<代码>:as
将捕获原始输入,而不管通过
&
等应用默认值或封装其余元素

引用

也可以选择在绑定形式中使用:或键,后跟另一个键 map可用于为部分或所有键提供默认值 如果在init expr中找不到它们

最后,也是可选的,:as后跟一个符号将导致 要绑定到整个init expr的符号


我不富有,所以很明显我没有选择如何工作,但我可以想出几个原因,当前的行为比你预期的好

  • 它更快。Clojure的许多低级核心功能在您的程序中一直得到使用,它们的优化更多是为了速度而不是优雅,以获得可接受的性能。当然,如果这是一个正确性的问题,那将是一个不同的故事,但是这里有两种合理的方法来解释
    :as
    的行为,因此选择更快的方法似乎是一个好计划。至于为什么它更快,我想这是显而易见的,但是:我们已经有了一个指向原始地图的指针,我们可以重用它。要使用“修改过的”映射,我们必须通过一系列assoc调用来构建它

  • 如果
    :as
    没有返回原始对象,您如何获得原始对象?你不能,真的,对吗?如果
    :as
    返回原始对象,则可以根据需要轻松构建修改后的版本。所以一种行为会给你留下更多的选择


  • 啊!!第二点我完全不明白。回想起来,它不应该这样做。非常感谢。