gpt4 book ai didi

lisp - Lisp 中简单与复杂的用户输入函数

转载 作者:太空宇宙 更新时间:2023-11-03 19:02:46 30 4
gpt4 key购买 nike

在此站点:http://www.gigamonkeys.com/book/practical-a-simple-database.html有如下列出的用户入口函数:

(defun prompt-read (prompt)
(format *query-io* "~%~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))

与以下更简单的形式相比,上述功能是否有任何主要优势:

(defun prompt-read2 (prompt)
(format t "~%~a: " prompt)
(setf answer (read-line)))

是否建议一直使用force-output*query-io*

最佳答案

将答案设置为这样的全局变量是不好的。你应该只返回答案,让调用者用它做它想做的事。如果您确实使用特殊(~全局)变量,则应在名称周围加上星号(*ANSWER* 而不是 ANSWER)。

需要

FORCE-OUTPUT 来确保用户在必须回答之前实际看到提示。如果我在终端中使用 SBCL 运行第二个版本,程序只会卡住以等待输入,什么也不说。

*QUERY-IO* 应用于向用户查询内容,因为某些环境可能希望以不同于其他输出的方式处理它。例如,有人可能会为您的程序编写一个 GUI 包装器,将查询转换为图形对话框。或者他们可能想将其作为脚本的一部分运行,提供来自字符串的输入。

(defun prompt-read (prompt)
(format *query-io* "~%~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))

(defun hello ()
(format t "~&Hello ~a!~%" (prompt-read "What's your name")))

(defmacro with-input ((input) &body body)
`(let ((*query-io* (make-two-way-stream (make-string-input-stream ,input)
(make-string-output-stream))))
,@body))

(defun test ()
(with-input ("jkiiski")
(hello))
(with-input ("rnso")
(hello)))
(test)
; Hello jkiiski!
; Hello rnso!

编辑

使用 SBCL 灰色流的更复杂示例。

(defclass foo-stream (sb-gray:fundamental-character-input-stream)
((output-input-script :initarg :script :accessor foo-stream-script)
(output-stream :initarg :out :accessor foo-stream-out)
(current-input :initform nil :accessor foo-stream-current-input)))

(defmethod sb-gray:stream-read-char ((stream foo-stream))
(with-accessors ((input foo-stream-current-input)
(out foo-stream-out)
(script foo-stream-script)) stream
(when (or (null input)
(not (listen input)))
(let ((output (string-trim '(#\space #\newline)
(get-output-stream-string out))))
(setf input (make-string-input-stream
(format nil "~a~%"
(cdr (assoc output script :test #'string=)))))))
(read-char input)))

(defun prompt-read (prompt)
(format *query-io* "~%~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))

(defun hello ()
(format t "~&Hello ~a!~%" (prompt-read "What's your name"))
(format t "~&I'm ~a too!" (prompt-read "How are you"))
(format t "~&~a~%" (if (string-equal (prompt-read
"Do you want to delete all your files")
"yes")
"Deleting all files... (not really)"
"Not deleting anything.")))

(defmacro with-input-script ((script) &body body)
(let ((out-sym (gensym "out")))
`(let* ((,out-sym (make-string-output-stream))
(*query-io* (make-two-way-stream
(make-instance 'foo-stream
:out ,out-sym
:script ,script)
,out-sym)))
,@body)))

(defun test ()
(with-input-script ('(("What's your name:" . "jkiiski")
("How are you:" . "great")
("Do you want to delete all your files:" . "No")))
(hello))
(with-input-script ('(("What's your name:" . "Foo Bar")
("How are you:" . "fine")
("Do you want to delete all your files:" . "Yes")))
(hello)))

(test)
; Hello jkiiski!
; I'm great too!
; Not deleting anything.
; Hello Foo Bar!
; I'm fine too!
; Deleting all files... (not really)

关于lisp - Lisp 中简单与复杂的用户输入函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38306229/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com