在Clojure中实施中断 [英] Implementing break in Clojure

查看:68
本文介绍了在Clojure中实施中断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果条件匹配返回最后一个值,是否有办法打破Clojure中的循环?大多数算法从发现结果时返回结果并避免完成整个执行过程中受益。

Is there a way to break out of a loop in Clojure if a condition is matched returning the last value? Most algorithms benefit from returning a result when they find it and avoiding completing the whole execution.

比方说,我有一个从0到100的100个数字向量,我想找到数字10。一旦找到10,我想停止执行。

Let's say that I have a vector of 100 numbers ranging from 0 to 100 and I want to find the number 10. Once 10 is found I want the execution to stop.

比我的示例更简单的情况如下:

An even simpler case than my example is the following:

(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中不存在,但我觉得有些牵强。即使是这种情况,我也可以自己执行类似的事情吗?

I have searched enough and I can't find any way of implementing this. I have also found an answer here that states that what I am asking doesn't exist in Clojure but I find it a little far-fetched. Even if this is the case can I implement something like that myself?

(我是Clojure的新手。)

(I am new to Clojure.)

推荐答案

您几乎完全正确。重新格式化您的代码,我们会得到

You nearly got it right. Reformatting your code, we get

(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 ,并希望该函数返回您的消息。

... where - for simplicity - I've got rid of the println, and had the function hopefully return your message.

但是,正如您所注意到的,它不是:

But, as you've noticed, it doesn't:

(MySearch 0)
;nil

为什么?

问题在于(重复...)外部中, if


  • 如果(< y 10)条件满足满足时,(如果...)
    满足 (递归...)依次执行,并返回后者
    的结果。

  • 最终, y 10 ,因此条件失败时,因此
    时返回 nil

  • If the (< y 10) condition for the when is met, the (if ...) and the (recur ...) are executed in turn, and the result of the latter returned.
  • Eventually, y is 10, so the when condition fails, so the when returns nil.

内部如果

Let's move the recur 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!"

由于我们返回了消息,因此我们知道该函数确实停止了执行。否则它将继续并返回 nil

Because we returned the message, we know that the function did stop executing. Otherwise it would have gone on and returned nil.

在已安装 println 的情况下,该函数将输出消息并返回 nil 立即执行,因为它会继续执行。所以-关于它是否停止执行,您再也不明智了。

With the println in place, the function would output the message and return nil immediately, as it would do had it gone on executing. So - as to whether it stopped executing, you're none the wiser.

顺便说一下,作为找到牵强的 的答案,让我再试一次:

By the way, as the author of the answer you find far-fetched, let me try again:


  • Clojure中没有中断声明

  • 反之亦然:

  • There is no break statement in Clojure.
  • It's the other way round:


  • 默认情况下,您跳出循环。

  • 您必须使用 recurr 才能继续。

  • You break out of a loop by default.
  • You have to use recur to continue it.

recur 是对该函数的特殊递归调用(或循环),您正在执行:

recur is a special recursive call to the function (or loop) you are executing:


  • 其中一个是返回值。

  • 据说处于尾巴位置

  • one where it is the returned value.
  • It is said to be in tail position.

大多数Lisp系统会自动检测到此类呼叫-所谓的 tail呼叫
因此,他们没有或需要像 recur 这样的构造。

Most Lisp systems detect such calls - so called tail calls - automatically. So they don't have or need a construct like recur.

话虽如此,Clojure 1.5引入了 reduced :a <类似code> break 的减少结构。您可以在此处中阅读。

Having said that, Clojure 1.5 introduced reduced: a break-like construct for reduce. You can read about it here.

这篇关于在Clojure中实施中断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆