Clojure let 绑定表单
Posted
技术标签:
【中文标题】Clojure let 绑定表单【英文标题】:Clojure let binding forms 【发布时间】:2014-06-19 21:33:25 【问题描述】:我试图了解 let 绑定如何在地图方面以闭包方式工作。据我了解,let 后跟一个向量,其中第一项是我要绑定的符号,然后是我要绑定到的值。所以
(let [a 1 b 2] a)
将给出 1 的值。
所以如果我声明地图如
(def people :firstName "John" :lastName "Doe")
我想绑定键 firstName 那么这将是简单“Hello Person”的正确形式
(let [personName (:firstName people)] (str "hello " personName))
这可行,但是在 Clojure 网站 http://clojure.org/special_forms#binding-forms 上,它们显示了另一种形式,也可以使用
(let [personName :firstName people] (str "hello " personName))
两个代码 sn-ps 都可以工作,我理解为什么第一个版本可以工作,但我对第二个版本的语法感到困惑。这只是语法糖还是重复的工作方式,并且比另一种更惯用?
【问题讨论】:
请参阅您链接到的文档中的地图绑定解构部分。 您的地图中没有键:name
。
对不起,我把钥匙命名错了。
【参考方案1】:
最后一种形式是地图绑定解构。如果您想将多个变量绑定到同一张地图的不同元素,这是最有用的:
(let [firstName :firstName lastName :lastName address :address people]
(str "hello " firstName " " lastName ", I see you live at " address))
如果你用前面的语法写出来,那就是:
(let [firstName (:firstName people) lastName (:lastName people) address (:address people)]
(str "hello " firstName " " lastName ", I see you live at " address))
如您所见,这使您不必在每个绑定中重复 people
。如果映射是计算的结果,它就不必将变量绑定到它,以便您可以重复它。
解构还允许您以类似于您正在访问的数据结构的格式布置绑定构造。这使得它更适合复杂的结构。
【讨论】:
user2766755,你可以对其他数据结构做类似的事情:(def x [5 10]) (let [[x1 x2] x] (* x1 x2)) => 50
。有些人觉得映射绑定解构语法有点奇怪,因为键在它们限定的局部变量之后。 (例如,我有这种感觉。)但是,“关键秒”语法总体上似乎更有用是有原因的。 Here 是对该问题的一次讨论。
更短的解构地图的方法是:(let [:keys [firstName lastName address] people] (println firstName lastName address))
【参考方案2】:
只是说清楚(我希望不要太迂腐)......
在
(let [personName (:firstName people)] (str "hello " personName))
您没有将密钥 :firstname
绑定到任何东西;您将标识符personName
绑定到关键字:firstname
作为函数 到映射people
的应用。
在
(let [personName :firstName people] (str "hello " personName))
您正在解构映射people
,将标识符personName
绑定到它在键:firstname
处的值。
PS
这个奇迹是由let
表单调用的destructure
函数实现的。查看它的作用可能会有所帮助。例如,
(destructure '[personName :firstName people])
;[map__779
; people
; map__779
; (if
; (clojure.core/seq? map__779)
; (clojure.lang.PersistentHashMap/create (clojure.core/seq map__779))
; map__779)
; personName
; (clojure.core/get map__779 :firstName)]
我接受了这个想法here。
【讨论】:
以上是关于Clojure let 绑定表单的主要内容,如果未能解决你的问题,请参考以下文章
在没有嵌套 let 的情况下在 Clojure 中绑定多个相关变量
Clojure 交换!在 let 绑定中的 map 函数内不起作用