Clojure:虽然 let 绑定不像绑定那样工作?
Posted
技术标签:
【中文标题】Clojure:虽然 let 绑定不像绑定那样工作?【英文标题】:Clojure: Why let binding doesnt work like for binding? 【发布时间】:2018-08-27 08:37:32 【问题描述】:所以,我有一个带钥匙的clojure.lang.PersistentArrayMap
,里面还有另一个clojure.lang.PersistentArrayMap
,比如:
:foo :bar "bar"
当我将for
与绑定一起使用时:
(for [[key value] :foo :bar "bar"] do-something)
它工作正常,但是当我尝试使用let
时,它不起作用......
(let [[key value] :foo :bar "bar"] do-something)
有人可以帮助我了解 let 绑定的工作原理吗? 谢谢!
【问题讨论】:
因为到目前为止这两个答案都没有明确警告它:默认情况下地图没有排序或排序。它们以插入顺序排列的条目很少,因此您的示例可以工作;但请确保您的地图只有一个用于该用例的条目。 【参考方案1】:以下是您的数据示例:
(forv [[key value] :foo :bar "bar"] ...)
key => :foo
value => :bar "bar"
(let [[key value] (first (seq :foo :bar "bar"))] ...)
key => :foo
value => :bar "bar"
您需要first
从序列中仅获取一个MapEntry
。
请注意,如果您只需要第一个,则实际上并不需要 seq
,因为 first
在其参数上内部调用 seq
:
(let [[key value] (first :foo :bar "bar")] ; same result
【讨论】:
【参考方案2】:使用for
,您可以从所有MapEntry
s 中创建一个序列(我们现在称它们为key-vals)。 for
是列表理解,而不是 for 循环,因此您正在创建一个列表(更具体的惰性序列),从绑定到输入上的连续值。
在let
中,您不会绑定到连续的值,而是绑定到一个值,除非您使用解构,在这种解构中您可以从某个序列中同时提取多个值。
使用let
,您只能将第一个和第二个键值绑定到key
和value
,但这不受支持,因为映射没有明确的顺序。
但是使用seq
,您可以从地图中获得两个键值:
(let [[a b] (seq :a 1 :b 2)] [a b])
;;=> [[:a 1] [:b 2]]
【讨论】:
你能帮我展示一些关于你的答案的例子吗?文档示例有时过于复杂 添加示例。以上是关于Clojure:虽然 let 绑定不像绑定那样工作?的主要内容,如果未能解决你的问题,请参考以下文章
Clojure 交换!在 let 绑定中的 map 函数内不起作用
在没有嵌套 let 的情况下在 Clojure 中绑定多个相关变量