2016-04-15 15 views
7

Tôi đang cố dịch một chương trình bàn điều khiển nhỏ mà tôi đã viết bằng Java vào Clojure, nhưng tôi gặp một chút rắc rối khi tìm ra sự khác biệt giữa tiêu chuẩn *out* var của Clojure và đối tượng tại System/out. Tôi đã có ấn tượng rằng chúng giống nhau, nhưng khi trong quá trình thử nghiệm, chúng dường như khác nhau.Clojure: * out * vs System/out

Trong chương trình của mình, tôi nhắc người dùng nhập số và tôi muốn văn bản nhắc và nhập văn bản nằm trên cùng một dòng. Trong Java, tôi đã in dấu nhắc với System.out.print() và sau đó Máy quét đọc đầu vào.

Sau đây là nỗ lực đầu tiên của tôi về điều gì đó tương tự trong Clojure. Mặc dù print chức năng có vẻ như nó sẽ kích hoạt trước khi read-line, nó ngay lập tức khối trên đầu vào và in tất cả mọi thứ sau trong một mớ hỗn độn lộn xộn:

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

Sau đây là nỗ lực tiếp theo của tôi, sử dụng *out*. Nó bị vấn đề tương tự như các chức năng trên:

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

Mở thử thứ ba của tôi, cuối cùng tôi đã nhận nó để làm việc bằng cách sử dụng System/out trực tiếp:

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

Tôi vui vì cuối cùng tôi đã nhận nó để công việc, nhưng tôi vô cùng bối rối là tại sao người thứ ba lại làm việc theo cách tôi muốn khi hai người đầu tiên không làm. Tại sao hai khối đầu tiên ngay lập tức? Bất cứ ai có thể làm sáng tỏ về điều này?

Trả lời

8

mỗi the docs:

*out* - Một đối tượng java.io.Writer đại diện đầu ra tiêu chuẩn cho các hoạt động in. Mặc định cho Hệ thống/out, được bao bọc trong một OutputStreamWriter

... vì vậy, bạn có một lớp gói. Nhìn vào tài liệu for that layer (nhấn mạnh thêm):

Mỗi lần gọi phương thức write() làm cho bộ chuyển đổi mã hóa được gọi trên (các) ký tự đã cho. Các byte kết quả được tích lũy trong bộ đệm trước khi được ghi vào luồng đầu ra cơ bản. Kích thước của bộ đệm này có thể được chỉ định, nhưng theo mặc định nó đủ lớn cho hầu hết các mục đích. Lưu ý rằng các ký tự được chuyển tới phương thức write() không được đệm.

... nhấn mạnh được thêm vào. Vì OutputStreamWriter bộ đệm, bạn cần gọi tới số .flush để buộc nội dung được ghi.

+0

Tôi thấy bây giờ đã được lưu vào bộ đệm và trước tiên tôi cần phải gọi .flush trên đó. Tôi đã không nhận ra rằng đó là một dòng và người kia là một nhà văn. Cảm ơn! – RGrun