在clojure中解构map函数参数:map需要最后去吗?



我试图定义一个函数,它接受一个map和一个常规参数,我想解构map的部分,比如

(defn do-stuff
[[{:keys [foo bar]} where] what]
(println foo bar what))

但是当我调用这个函数时,我得到了一个错误

; Execution error (UnsupportedOperationException) at .../do-stuff (REPL:34).
; nth not supported on this type: PersistentArrayMap

如果我交换函数参数

(defn do-stuff
[what [{:keys [foo bar]} where]]
(println foo bar what))

一切正常。当然,我可以在函数内编写一个let并在那里进行解构,但我想知道我错过了什么…

编辑澄清一下,我希望能够像

这样调用函数
(do-stuff {:foo "something" :bar "something else"} "baz")

既然你没有告诉我们,你的呼叫是什么,我猜是您混淆了用于解构的let语法功能。

所以下面的调用可以工作——注意在映射的vector中的嵌套和悬垂的where:

(defn do-stuff
[[{:keys [foo bar]} where] what]
(println foo bar what))
(do-stuff [{:foo 1 :bar 2} 3] 4)
; 1 2 4
(defn do-stuff
[what [{:keys [foo bar]} where]]
(println foo bar what))
(do-stuff 0 [{:foo 1 :bar 2} 3])
; 1 2 0

虽然您不打印where,但似乎您想要保留地图本身。但这是通过:as完成的。

(defn do-stuff
[{:keys [foo bar] :as where} what]
(println foo bar where what))
(do-stuff {:foo 1 :bar 2 :baz 3} 4)
; 1 2 {:foo 1, :bar 2, :baz 3} 4

编辑

事情发生的原因可以追溯到:

位置解构适用于字符串(它给出字符on位置,但是映射解构失败,因为char是no地图。但它优雅地失败了,只是将nil分配给两个键变量。

但是当提供映射时,它会失败,因为它们不能(通过nth访问),因此出现错误信息。

(defn do-stuff
[[{:keys [foo bar]}]]
(println foo bar))
(do-stuff "baz")
; nil nil
(do-stuff {:foo "something" :bar "something else"})
; throws

相关内容

  • 没有找到相关文章

最新更新