在Clojure中实现break

Ada*_*dam 5 clojure

如果条件匹配返回最后一个值,有没有办法在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 ...)依次执行,并返回后者的结果.
  • 最终,y10,所以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立即,因为它会做过它走了上执行.那么 - 至于它是否停止执行,你就不是更聪明了.


顺便说一下,作为答案的作者,你会发现很多东西,让我再试一次:

  • Clojure中没有中断声明.
  • 反过来说:

    • 默认情况下,您会跳出循环.
    • 你必须用recur它来继续它.
  • recur是对loop正在执行的函数(或)的特殊递归调用:

    • 一个是返回值.
    • 据说它处于尾部位置.

大多数Lisp系统会自动检测此类调用 - 即所谓的尾调用.所以他们没有或不需要像这样的结构recur.


话虽如此,Clojure 1.5引入了reduced:break类似于减少的构造.你可以在这里阅读它.