我正在经历4clojure问题,我无法理解为什么以下代码工作
user=> ((fn foo [x] (when (> x 0) (conj (foo (dec x)) x))) 5)
(5 4 3 2 1)
Run Code Online (Sandbox Code Playgroud)
我知道(foo (dec x))必须将其视为PersistentCollection才能使其工作,但正在发生的事情是个谜.任何洞察它为什么工作,以及为什么在这个顺序将不胜感激.
让我们仔细看看您的代码示例.基本上,它只是一个(foo 5)具有以下foo功能的函数调用:
(defn foo [x]
(when (> x 0)
(conj (foo (dec x)) x)))
Run Code Online (Sandbox Code Playgroud)
当你foo用任何非正值调用x它时返回nil.否则它conj会将x调用结果返回给调用结果(foo (dec x)).
因此,调用(foo 2)大致相当于以下代码:
(conj (conj nil 1) 2)
Run Code Online (Sandbox Code Playgroud)
可能会让您感到困惑的是conj将nil值作为第一个参数传递的行为.
conj威胁nil作为空列表(),因此(conj nil 1)产生相同的结果(conj () 1).此行为记录在conj文档中:
=> (doc conj)
(doc conj)
-------------------------
clojure.core/conj
([coll x] [coll x & xs])
conj[oin]. Returns a new collection with the xs
'added'. (conj nil item) returns (item). The 'addition' may
happen at different 'places' depending on the concrete type.
Run Code Online (Sandbox Code Playgroud)
另一件可能让您感到困惑的事情是结果列表中元素的顺序.conj旨在以PersistentCollection最有效的方式添加新元素.如果列表conj 将新元素添加到原始列表的开头:
=> (conj '(1) 2)
(2 1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
137 次 |
| 最近记录: |