如果条件匹配返回最后一个值,有没有办法在 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)
当我找到5个的时候我怎么能停下来呢?
我已经进行了足够的搜索,但找不到任何实现此目的的方法。我还在这里找到了一个答案,指出我所要求的内容在 Clojure 中不存在,但我发现它有点牵强。即使是这样,我可以自己实施类似的事情吗?
(我是 Clojure 新手。)
你几乎做对了。重新格式化您的代码,我们得到
(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))))
...为了简单起见,我已经摆脱了println
,并让该函数希望返回您的消息。
但是,正如您所注意到的,它没有:
(MySearch 0)
;nil
Why?
问题在于(recur ...)
is outside the if
。这是做什么的?
- If the
(< y 10)
的条件为when
满足时,则(if ...)
和
这(recur ...)
依次执行,最后的结果
回。
- 最终,
y
is 10
, 所以when
条件失败,所以when
回报nil
.
让我们移动递归inside the 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)))))
现在,你瞧:
(MySearch 0)
;"I found it! Now I want to stop executing!"
因为我们returned消息,我们知道该函数确实停止执行。否则它会继续并返回nil
.
随着println
在适当的位置,该函数将输出消息并返回nil
立即执行,就像继续执行一样。所以 - 至于它是否停止执行,你一无所知。
顺便说一句,作为作者你找到的答案牵强的 https://stackoverflow.com/a/26422738/1562315, 让我再尝试一次:
大多数 Lisp 系统都会检测到此类调用 - 所谓的尾部调用- 自动地。
所以他们没有或不需要像这样的结构recur
.
话虽如此,Clojure 1.5 引入了reduced
: a break
类似于reduce 的构造。你可以阅读相关内容here https://stackoverflow.com/a/25107476/1562315.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)