2009-06-28 12 views
3

Wenn die Länge 4 ist, wird die folgende Schleife 5 mal ausgeführt. 5 Zeichen aus dem Stream lesenClojure-Schleife liest eine zusätzliche


(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))))) 

Antwort

3

Sie sollten für zero? testen, bevor Sie die read tun. Beachten Sie, dass Ihre Version read einmal aufrufen wird, selbst wenn length == 0, um mit zu beginnen.

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

Ein anderer Weg, die eine explizite loop vermeidet: für Null vor der Schleife einen weiteren Test hinzufügen

(apply str 
     (take length 
      (repeatedly #(let [c (char (.read stream))] 
          (println "=>" c) c))))) 
+0

Also ich sollte, aber ich noch nicht bekommen, warum es 5 Mal ausgeführt wird? Ist das das Clojure-Verhalten oder fehlt mir etwas? –

+1

Ihre Version liest, wenn Zähler = 4, 3, 2, 1, 0. Das sind fünf Iterationen. Der erste Lesevorgang wird innerhalb des Schleifenbindungsvektors durchgeführt, um zunächst "i" einzurichten, und die nächsten vier Lesevorgänge erfolgen über "recur". Wenn Sie 'counter' für' zero? 'Testen, haben Sie bereits einen zu viel gelesen. Die Version, die ich gepostet habe, verschiebt den Lesevorgang in die if-Anweisung, wodurch dieses Problem vermieden wird. Sie brauchen keinen weiteren Test vor der Schleife. –

+0

Gehe durch deine Schleife in deinem Kopf, du wirst sehen, woher das fünfte Zeichen kommt. Im Grunde genommen ist das Wiederholen der gleichen Sache (.read-stream) an zwei Stellen in der Schleife ein Code-Geruch. – Svante

0

Ich weiß nicht, Clojure, aber es scheint mir, wie Sie den Strom wieder in „Ergebnis“ Form lesen, das ist wie endgültig in CL?