【问题标题】:In Clojure, how can I terminate this loop properly在 Clojure 中,如何正确终止此循环
【发布时间】:2013-03-06 22:31:38
【问题描述】:

我刚接触 Clojure,想做一些简单的函数来弄湿我的脚,并尝试摆脱我的命令式编程背景。

下面的代码只是在字符串中搜索重复元素,但循环似乎使其失控;我做错了什么?是的,这可能看起来势在必行;我仍在尝试围绕函数式编程和非状态更改。是的,html 没有经过验证,我只是以它为例。

(def src "
  <html>
  <head>
  <title>Astronomy
  </title>
  <title>Science
  </title>
  </head>
  </html>
")


(defn findit [ele body i]
  (let [n (.indexOf body (clojure.string/join ["<" ele ">"]) i)]
    (if (> n -1)
      (let [n2 (.indexOf body (clojure.string/join ["</" ele ">"]) (+ n 1))] ;if we found opening element, then find closing element
        (if (> n2 -1) ;found both open and close of element?
          [(subs body (+ n (.length ele) 2) n2) (+ n2 1)]))))
  )

; (let [[r i] (findit "title" src 69)] (println i) (if r (println r,i)))

(defn findthem [ele body]
  (loop [x 0]
    (let [[r i] (findit ele body 0)]
      (println r,i)
      (if i
        (recur i)))
    )
  )

(findthem "title" src)

【问题讨论】:

  • 试试这个可能对你有帮助:(loop [x 0] (println "hello") (let [i 42] (if i (recur i)))))
  • 这会导致无限循环,对吗?不会是 (recur (- i 1)) 或类似的东西来帮助它减少和停止循环吗?

标签: loops clojure


【解决方案1】:

在循环的每次迭代出现的let 语句中,findit 被调用,索引为0,而不是x(或i)。

(defn findthem [ele body]
  (loop [i 0]
    (let [[r i] (findit ele body i)]
      (println r i)
      (when i
        (recur i)))))

【讨论】:

  • 谢谢,我明白我在这里做错了什么;擦除和重写代码,我忘了把它们放在一起!使用 when 与 if 有什么好处?
  • @scape: 当你的代码只用于真条件时,请使用when 否则使用if.. 只是为了使其更具可读性
  • @scape Plus,when 包含一个隐含的 do(即,它的主体可以包含任意数量的语句),因此,例如,如果您只想在 i 为不是nil,你可以写(when i (println r i) (recur i))
猜你喜欢
  • 2013-04-22
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 2016-02-20
  • 2021-06-22
相关资源
最近更新 更多