【问题标题】:Error in recur call in ClojureClojure 中的重复调用错误
【发布时间】:2016-01-28 13:06:19
【问题描述】:

我正在尝试从输入中读取数字并将它们打印回 Clojure,直到我读取到数字 42。确保我知道如何读取输入的非常基本的事情。取自codechef

我写了这个程序。可能不是很好的clojure。

(defn universe
  []
  (let [num (line-seq (java.io.BufferedReader. *in*))]
    (if (not= num 42)
      (do
        (println num)
        (recur (universe))
        )
      )
    )
  )

我的理解是line-seq 懒惰地从给出的任何读者评估。在这种情况下是标准输入。

所以我让它成为数字。然后如果 num 不是 42 我打印它然后递归调用 Universe。但它会抛出异常

Mismatched argument count to recur, expected: 0 args, got: 1,

我见过example 并且 recur 确实需要一个参数。看着official documentation,我看不到它的语法。那么为什么会出现这个错误呢?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    recur 不使用要重复到的位置的名称。相反,recur 特殊形式会跳回到最接近的函数或loop 表达式,以更接近者为准。然后它传递不同的参数。这使您可以在处理数据时重复执行相同的代码块,并且没有函数调用开销。

    在您的情况下,它会重复到函数调用:

    (defn universe [] ...
    

    并试图向它传递一个参数,但由于函数 Universe 不接受任何参数而失败。也许您打算在 if 周围放置一个 loop 表达式?

    user> (defn universe
            []
            (let [numbers (line-seq (java.io.BufferedReader. *in*))]
              (loop [numbers numbers]
                (let [num (first numbers)]
                  (if (not= (Integer/parseInt num) 42)
                    (do
                      (println num)
                      (recur (rest numbers))))))))
    #'user/universe
    user> (universe)
    3   ;; typed 3 
    nil ;; typed 42
    

    或者您打算在函数顶部重复执行,在这种情况下,只需调用 (recur) 而不是 (recur universe)

    【讨论】:

    • 逻辑是有道理的,但是这两种方式中的任何一种都不起作用。只是调用 recur 而不是 (recur universe) 会得到一个无限循环。我已经停止了 REPL。即使在 let 之后添加 println 也不会给我任何输出。像您所做的那样放置一个循环会将lazySeq的CastException传递给String。我认为这可能是因为(第一个数字)是参数值。所以尝试在循环中添加另一个 let 以获得第一个。然后得到另一个无限循环。在 Ubuntu 14.04 上使用 Clojure 1.7 和 OpenJDK 64 位服务器 VM 1.7.0_79-b14。以防万一。
    • 对于任何recur 调用,无论是loop 还是函数形式,肯定没有函数调用开销
    • 你的逻辑看起来有问题。 loop 设置了num 绑定到(first numbers),但recur 绑定它到(rest numbers),肯定不兼容。除了。 numbers 因此(rest numbers)loop 中是不变的。
    • @Thumbnail 哎呀,我粘贴了完全错误的代码块:-/ 在点击之前没有阅读我的帖子。对此感到抱歉,感谢您指出这一点。这次我粘贴了 repl 的输出,所以它应该可以工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2018-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多