2016-04-15 19 views
7

Próbuję przetłumaczyć mały program konsoli, który napisałem w Javie, na Clojure, ale mam trochę problemów z ustaleniem różnicy między standardowym kodem Clojure *out* var a obiektem w System/out. Miałem wrażenie, że są to te same rzeczy, ale kiedy podczas moich testów wydają się być inne.Clojure: * out * vs System/out

W moim programie poproszę użytkownika o wprowadzenie numeru, a ja chcę, aby tekst zachęty i tekst wejściowy były w tej samej linii. W Javie wydrukowałem prompt z System.out.print(), a następnie skaner odczytał dane wejściowe.

Oto moja pierwsza próba podobieństwa w Clojure. Choć funkcja print wydaje się, że powinna zwolnić przed read-line, natychmiast bloki na wejściu i drukuje wszystko po w pomieszane bałagan:

(defn inp1 [] 
    (print "Enter your input: ") 
    (let [in (read-line)] 
     (println "Your input is: " in))) 

Poniższa była moja kolejna próba, używając *out*. cierpi ona z tego samego problemu w funkcji powyżej:

(defn inp2 [] 
    (.print *out* "Enter input: ") 
    (let [i (read-line)] 
     (println "You entered: " i))) 

Na moim trzecim razem, w końcu dostał go do pracy przy użyciu System/out bezpośrednio:

(defn inp3 [] 
    (let [o System/out] 
     (.print o "Enter input: ") 
     (let [i (read-line)] 
      (println "You entered: " i)))) 

Cieszę się, że wreszcie go pracuję, ale jestem głęboko zmieszany, dlaczego trzeci działa tak, jak chcę, kiedy pierwsze dwa nie. Dlaczego dwa pierwsze bloki natychmiast? Czy ktoś może rzucić trochę światła na to?

Odpowiedz

8

Per the docs:

*out* - Obiekt java.io.Writer stanowiących standardowe wyjście dla operacji drukowania. Domyślnie System/out, zapakowane w OutputStreamWriter

... więc masz warstwę owijania. Patrząc na docs for that layer (podkreślenie dodane):

każdego wywołania write() metoda powoduje, że konwerter kodowania powoływać się na danym znaku (ów). Wynikowe bajty są kumulowane w buforze przed zapisaniem do wyjściowego strumienia wyjściowego. Rozmiar tego bufora może być określony, ale domyślnie jest wystarczająco duży dla większości celów. Zauważ, że znaki przekazane do metod write() nie są buforowane.

... dodano podkreślenia. Od OutputStreamWriter buforów, musisz zadzwonić pod numer .flush, aby wymusić zapisanie treści.

+0

Teraz widzę, że jest zbuforowany i muszę najpierw wywołać flush. Nie zdawałem sobie sprawy, że jeden jest strumieniem, a drugi pisarzem. Dzięki! – RGrun