Clojure - recur 适用于循环或 let 语句?
Posted
技术标签:
【中文标题】Clojure - recur 适用于循环或 let 语句?【英文标题】:Clojure - recur applies to loop or let statement? 【发布时间】:2017-06-04 14:14:50 【问题描述】:我在 Clojure 中有一个关于 recur 的问题。如果我在循环中有一个 let 语句,recur 调用是否可以应用于 let 语句而不是循环的值? 例如,在这种情况下:
(defn someFunction [listA listB]
("do something here...."
[new-listA new-listB]))
(defn anotherFunction [listA listB]
("do something here...."
[new-listA new-listB]))
(defn myFunction [firstList secondList]
(loop [list1 (someMutation firstList)
list2 (someMutation secondList)]
(if (= "true" (someCondition))
(let [[newlist1 newlist2]
(someFunction list1 list2)]
(recur newlist1 newlist2))
(anotherFunction list1 list2) )))
(recur newlist1 newlist2) 是应用于循环还是应用于 let? 有没有办法跳过这个 let 语句并直接使用“someFunction”返回的两个值调用 recur,假设我不能改变“someFunction”返回一个带有两个参数的向量的事实?
【问题讨论】:
【参考方案1】:recur
总是递归到最接近的loop
或函数,以更接近recur
的形式为准。它通过编译本质上是一个循环/跳转语句来完成此操作,该语句更改循环变量的值,然后跳回到循环/fn 点。这样它只使用一个堆栈帧并且可以全速运行。这种设计有一些有意的取舍:
最后一个要求您保留 let 表达式或类似的东西,例如解构形式。循环确实允许像函数一样解构参数:
(loop [[a b] [1 2]]
(println a b)
(if (< a 10)
(recur [(inc a) (inc b)])))
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
因此您可以编写循环表达式以直接获取someFunction
的结果
(loop [[list1 list2] [(someMutation firstList) (someMutation secondList)]]
...
(recur (someFunction ...))
【讨论】:
【参考方案2】:let
不是有效的重复目标。
您也许可以在 let 中进行设置以解构向量,因此也可以跳过 let。
另外,引用 true
有点奇怪。这在你的控制之下吗?如果是这样,应该只寻找布尔值 true 然后可以说(if (somecondition)...
【讨论】:
以上是关于Clojure - recur 适用于循环或 let 语句?的主要内容,如果未能解决你的问题,请参考以下文章