Clojure循环读取了一个额外的值

3
当长度为4时,以下循环执行5次。从流中读取5个字符。

(loop [i (.read stream)  result ""  counter length]
    (let [c (char i)]
      (println "=>" c)
      (if (zero? counter)
        result
        (recur (.read stream) (str result c) (dec counter)))))
2个回答

3

在执行read操作之前,您应该先测试是否为zero?。请注意,即使length一开始就等于0,您的版本也会调用read一次。

(loop [result "" counter length]
  (if (zero? counter)
    result
    (let [c (char (.read stream))]
      (println "=>" c )
      (recur (str result c) (dec counter)))))

另外一种避免显式循环的方式:
(apply str 
       (take length 
             (repeatedly #(let [c (char (.read stream))]
                            (println "=>" c) c)))))

所以在循环前我应该再添加另一个测试,但我仍然不明白为什么它会运行5次?这是Clojure的行为还是我漏掉了什么? - Hamza Yerlikaya
1
你的版本在计数器等于4、3、2、1、0时进行读取。这是五次迭代。第一次读取是在循环绑定向量内完成的,用于初始化i,接下来的四次读取通过recur完成。当你测试counter是否为zero?时,你已经多读了一次。我发布的版本将读取操作移到了if语句内部,从而避免了这个问题。在循环之前不需要进行另一个测试。 - Brian Carper
在脑海中逐步执行循环,您将看到第5个字符来自哪里。基本上,在循环中的两个位置重复相同的事情(.read stream)是一种代码异味。 - Svante

0

我不懂Clojure,但在我看来,你似乎又以“result”形式重新读取了流,这类似于CL中的final吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接