如果条件匹配返回最后一个值,有没有办法在Clojure中打破循环?大多数算法都会在找到结果时返回结果并避免完成整个执行.
假设我有一个100个数字的向量,范围从0到100,我想找到数字10.一旦找到10,我希望执行停止.
比我的例子更简单的情况如下:
(defn MySearch
[y]
(when (< y 10)
;;Corrected. Thanks to dsm who pointed it out. Previously was (< y 5).
(if (= (nth [1 2 3 4 5 6 7 8 9 10] y) 10)
(println
"I found it! Now I want to stop executing!"
)
)
(recur
(inc y)
)
)
)
(MySearch 0)
Run Code Online (Sandbox Code Playgroud)
当我找到5时我怎么能停下来?
我搜索得足够多,我找不到任何实现方法.我在这里也找到了一个答案,说明我所要求的并不存在于Clojure中,但我发现它有点牵强.即使是这种情况,我可以自己实现这样的东西吗?
(我是Clojure的新手.)
Thu*_*ail 13
你几乎把它弄好了.我们得到了重新格式化代码
(defn MySearch [y]
(when (< y 10)
(if (= (nth [1 2 3 4 5 6 7 8 9 10] y) 10)
"I found it! Now I want to stop executing!")
(recur (inc y))))
Run Code Online (Sandbox Code Playgroud)
...在哪里 - 为了简单起见 - 我已经摆脱了println,并且有功能希望返回你的信息.
但是,正如你所注意到的那样,它并没有:
(MySearch 0)
;nil
Run Code Online (Sandbox Code Playgroud)
为什么?
麻烦的是,(recur ...)是外面的if.这是做什么的?
(< y 10)该条件when被满足,(if ...)以及(recur ...)依次执行,并返回后者的结果.y是10,所以when条件失败,所以when
返回nil.让我们继续前进的易复发里面的if:
(defn MySearch [y]
(when (< y 10)
(if (= (nth [1 2 3 4 5 6 7 8 9 10] y) 10)
"I found it! Now I want to stop executing!"
(recur (inc y)))))
Run Code Online (Sandbox Code Playgroud)
现在,罗和贝恩:
(MySearch 0)
;"I found it! Now I want to stop executing!"
Run Code Online (Sandbox Code Playgroud)
因为我们返回了消息,所以我们知道函数确实停止了执行.否则它会继续并返回nil.
随着println到位,功能将输出消息并返回nil立即,因为它会做过它走了上执行.那么 - 至于它是否停止执行,你就不是更聪明了.
顺便说一下,作为答案的作者,你会发现很多东西,让我再试一次:
反过来说:
recur它来继续它.recur是对loop正在执行的函数(或)的特殊递归调用:
大多数Lisp系统会自动检测此类调用 - 即所谓的尾调用.所以他们没有或不需要像这样的结构recur.
话虽如此,Clojure 1.5引入了reduced:break类似于减少的构造.你可以在这里阅读它.