Clojure的Associative Destructuring允许人们通过数字索引来解构vector(也许是seq或list)。
这种模式是不是在clojure.org提到,到目前为止,但被中提到的Clojure的喜悦,第2版。迈克尔·福格斯(Michael Fogus),克里斯·豪斯(Chris Houser),2014年5月,第14页。59.这种方法出现在“关联解构”一节中-错误地是因为这种基于索引的解构只是“关联解构”的特例,在上述书中被称为“带地图的解构”。
无论如何,结果是意外的(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]
Run Code Online (Sandbox Code Playgroud)
但在清单上:
(let [{firstthing 0, lastthing 3} '(1 2 3 4)] [firstthing lastthing])
;=> [nil 4]
Run Code Online (Sandbox Code Playgroud)
为什么nil在位置0?
类似地:
(let [{firstthing 0, lastthing 3} (seq '(1 2 3 4))] [firstthing lastthing])
;=> [nil 4]
Run Code Online (Sandbox Code Playgroud)
但另一方面:
(let [{firstthing 0, lastthing 3} (vec (seq '(1 2 3 4)))] [firstthing lastthing])
;=> [1 4]
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
附录:
(let [{firstthing 0, lastthing 3} { 1 2 3 4 } ] [firstthing lastthing])
;=> [nil 4]
Run Code Online (Sandbox Code Playgroud)
...听起来是合理的,因为实际要被破坏的地图{1 2, 3 4}。因此,不是通过位置而是通过整数键(可以改变脚下的表达式的含义)进行查找的结果就是[nil 4]。是否将不是矢量的任何东西首先注入地图?
(let [{firstthing 10, lastthing 30} (seq '(10 2 30 4))] [firstthing lastthing])
;=> [2 4]
Run Code Online (Sandbox Code Playgroud)
看起来肯定像...
(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
Run Code Online (Sandbox Code Playgroud)
哦耶。
为什么在位置0处没有nil?
Run Code Online (Sandbox Code Playgroud)(let [{firstthing 0, lastthing 3} '(1 2 3 4)] [firstthing lastthing]) ;=> [nil 4]
如果您查看生成的代码let:
(let [{firstthing 0, lastthing 3} '(1 2 3 4)] [firstthing lastthing])
;=> [nil 4]
Run Code Online (Sandbox Code Playgroud)
您会看到,如果出现seq?,它将转换为地图。所以:
user=> (macroexpand '(let [{firstthing 0, lastthing 3} '(1 2 3 4)] [firstthing lastthing]))
(let*
[map__8012 (quote (1 2 3 4))
map__8012 (if (clojure.core/seq? map__8012)
(clojure.lang.PersistentHashMap/create (clojure.core/seq map__8012))
map__8012)
firstthing (clojure.core/get map__8012 0)
lastthing (clojure.core/get map__8012 3)]
[firstthing lastthing])
Run Code Online (Sandbox Code Playgroud)
因此,您获得nil密钥0和4密钥3。
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |