我正在使用clojure,虽然之前我已经涉足lisps,但我很难找到一种干净的方法来在cond语句中嵌入let语句.例如,请考虑以下功能:
(defn operate-on-list [xs]
(let [[unpack vector] (first xs)]
(cond
[(empty? xs) 'empty
unpack vector
:else (operate-on-list (rest xs))])))
Run Code Online (Sandbox Code Playgroud)
它是列表上非常标准的递归操作,但它需要在列表中的第一个元素上进行一些工作才能使用内容.当然,问题是列表可能是空的.
在这个例子中,改变unpack
to ((first xs) 0)
and vector
to 并不难((first xs) 1)
,但是如果需要做更多的工作(第一个xs),这很快就会变得很难看.
有没有办法在cond中有效地使用let语句?
谢谢.
-Nate
Mic*_*zyk 11
在这些情况下,您最好使用if-let
:
(defn operate-on-list [xs]
(if-let [[unpack v] (first xs)]
(cond
unpack v
:else (operate-on-list (rest xs)))))
Run Code Online (Sandbox Code Playgroud)
此代码遍历给定列表 seq-able(list,vector,array ...)的向量,并返回第一个向量的第二个元素,其第一个元素为true(表示不是false
或nil
).nil
如果没有找到这样的向量,则返回.
请注意,这vector
是一个内置函数,因此我选择v
作为变量名,以防万一将来需要在函数体中使用该函数.更重要的是,你在cond语法中使用了太多括号; 已修复此版本.
更新:另外两件值得注意的事情if-let
:
该方法if-let
的工作原理,如果(first xs)
恰好是nil
(false
将是相同的),解构绑定从来没有发生,所以Clojure中不会抱怨不能够绑定nil
到[unpack v]
.
另外,if-let
接受一个else子句(其中你不能引用if-let
绑定向量中绑定的变量- 尽管如果你在else子句中,你知道它们在哪里false
或者nil
无论如何).
归档时间: |
|
查看次数: |
2906 次 |
最近记录: |