2016-04-15 10 views
7

Ich versuche, ein kleines Konsolenprogramm, das ich in Java geschrieben habe, in Clojure zu übersetzen, aber ich habe ein wenig Mühe, den Unterschied zwischen Clojure Standard *out* var und das Objekt bei System/out. Ich hatte den Eindruck, dass sie das Gleiche waren, aber während meiner Tests scheinen sie anders zu sein.Clojure: * out * vs System/out

In meinem Programm fordere ich den Benutzer auf, eine Nummer einzugeben, und ich möchte, dass die Eingabeaufforderung und der Eingabetext in derselben Zeile stehen. In Java habe ich die Eingabeaufforderung mit System.out.print() ausgedruckt und dann hat ein Scanner die Eingabe gelesen.

Das folgende war mein erster Versuch etwas Ähnliches in Clojure. Obwohl die print Funktion scheint, wie es vor den read-line, es sofort Blöcken am Eingang und alles druckt Feuer soll nach in einem wirren Durcheinander:

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

Nachfolgend war mein nächster Versuch, *out* verwenden. Sie leidet unter dem gleichen Problem wie die Funktion oben:

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

Auf meinem dritten Versuch, ich habe es endlich unter Verwendung System/out direkt zu arbeiten:

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

Ich bin froh, dass ich es endlich zu Arbeit, aber ich bin zutiefst verwirrt, warum der dritte so funktioniert, wie ich es will, wenn die ersten beiden nicht funktionieren. Warum blockieren die ersten zwei sofort? Kann jemand etwas Licht dazu bringen?

Antwort

8

Per the docs:

*out* - A java.io.Writer Objekt Standardausgabe für Druckvorgänge darstellt. Defaults im System/out, in einem Output gewickelten

... so Sie eine Schicht von Verpackung haben. Mit Blick auf die Dokumentation for that layer (Hervorhebung hinzugefügt):

Jeder Aufruf einer Methode write() bewirkt, dass die Codierung Wandler auf der gegebenen Stelle (n) aufgerufen werden. Die resultierenden Bytes werden in einem Puffer gespeichert, bevor sie in den zugrunde liegenden Ausgabestream geschrieben werden. Die Größe dieses Puffers kann angegeben werden, ist aber standardmäßig groß genug für die meisten Zwecke. Beachten Sie, dass die an die write() -Methode übergebenen Zeichen nicht gepuffert sind.

... Hervorhebung hinzugefügt. Seit OutputStreamWriter Puffer, müssen Sie aufrufen, um zu schreiben Inhalt zu erzwingen.

+0

Ich sehe jetzt, dass es gepuffert ist, und ich muss zuerst anrufen. Ich wusste nicht, dass man ein Strom ist und der andere war ein Schriftsteller. Vielen Dank! – RGrun