我在Clojure中有一个关于复发的问题。如果我在循环中有一个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) )))
应用于循环或let的是(recur newlist1 newlist2)吗? 有没有一种方法可以跳过这个let语句并直接使用“someFunction”返回的两个值调用recur,假设我无法改变“someFunction”返回带有两个参数的向量的事实?
答案 0 :(得分:6)
$UserCal`:\calendar
始终会重复到最接近recur
形式的loop
或函数。它通过编译本质上是一个循环/跳转语句来改变循环变量的值,然后跳回到循环/ fn点。这样它只使用一个堆栈帧并可以全速运行。这种设计有一些有意的权衡:
最后一个要求你保留let表达式或类似的东西,例如解构形式。循环确实允许像函数一样对参数进行解构:
recur
因此,您可以编写循环表达式以直接获取 (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
答案 1 :(得分:1)
let
不是有效的重复目标。
你或许可以在let中设置构造向量的结构,因此也可以跳过let。
另外,等于true
有点奇怪。这是你的控制吗?如果是这样,应该只查找布尔值true然后可以说(if (somecondition)...