2009-06-28 5 views

답변

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

방지하는 또 다른 방법 loop 명시 :

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

그래서 내가 제로의 루프 전에 다른 검사를 추가해야하지만 5 회를 실행하는 이유는 아직하지 않는다? 이게 클로저 행동인가요? 아니면 뭔가 빠졌나요? –

+1

당신의 버전은 counter = 4, 3, 2, 1, 0 일 때 읽습니다. 그것은 다섯 번의 반복입니다. 첫 번째 읽기는 루프 바인딩 벡터 안에서 수행되어 처음에'i'를 설정하고, 다음 네 번의 읽기는'recur'를 통해 수행됩니다. 당신이'zero '를 위해'counter'를 테스트 할 때 당신은 이미 한 것을 너무 많이 읽었습니다. 내가 게시 한 버전은이 문 제를 피하는 if 문 내에서 읽음을 옮깁니다. 루프 전에 다른 테스트가 필요하지 않습니다. –

+0

머리를 감싸고 있으면 5 번째 문자가 나오는 위치를 알 수 있습니다. 기본적으로 루프의 두 위치에서 동일한 작업 (.read stream)을 반복하면 코드 냄새가 난다. – Svante

0

나는 clojure를 모르지만, "결과"형식으로 스트림을 다시 읽는 것처럼 보입니다. CL에서의 최종 결과입니까?