Clojure的关联解构允许按数字索引解构向量(也可能是序列或列表)。这种模式目前在clojure.org上没有提到,但在《The Joy of Clojure》第二版(Michael Fogus、Chris Houser,2014年5月,第59页)中提到。该书中有一个名为“关联解构”的部分,其中包含了这种方法——错误地将基于索引的解构称为“关联解构”的特例,而在该书中,实际上将其称为“使用映射进行解构”。
为什么在位置0有
同样地:
无论如何,结果都是出乎意料的(Clojure 1.10.0):
在所有情况下,提取索引0和3处的值。
以下内容符合预期:
(let [{firstthing 0, lastthing 3} [1 2 3 4]] [firstthing lastthing])
;=> [1 4]
(let [{firstthing 0, lastthing 3} (vec '(1 2 3 4))] [firstthing lastthing])
;=> [1 4]
但是在列表中:
(let [{firstthing 0, lastthing 3} '(1 2 3 4)] [firstthing lastthing])
;=> [nil 4]
为什么在位置0有
nil
?同样地:
(let [{firstthing 0, lastthing 3} (seq '(1 2 3 4))] [firstthing lastthing])
;=> [nil 4]
但另一方面:
(let [{firstthing 0, lastthing 3} (vec (seq '(1 2 3 4)))] [firstthing lastthing])
;=> [1 4]
这里发生了什么?
附录:
(let [{firstthing 0, lastthing 3} { 1 2 3 4 } ] [firstthing lastthing])
;=> [nil 4]
...听起来很合理,因为要关联销毁的地图实际上是{1 2, 3 4}
。因此,通过整数键(改变我们脚下表达式的含义)而不是位置进行查找的结果将完全是[nil 4]
。是否将任何不是向量的内容先倒入到地图中?
(let [{firstthing 10, lastthing 30} (seq '(10 2 30 4))] [firstthing lastthing])
;=> [2 4]
它确实看起来像是这样的....
(let [{firstthing 10, lastthing 30} (seq '(10 2 30 ))] [firstthing lastthing])
; Execution error (IllegalArgumentException) at user/eval367 (REPL:1).
; No value supplied for key: 30
哦,是的。
(map associative? [{} [] ()])
:(true true false)
。 - glts