我必须学习Scheme的基础知识来完成一个项目,但是我在构建等效的while循环时遇到了一些困难。例如,在下面的代码中,我想让用户输入一个字符。如果字符是x,我想要摆脱循环。如果是任何其他字符,将显示该字符,循环继续下一次迭代。
(define getUserChar (lambda ()
(define ch)
(let loop ()
(display "Enter character: ")
(set! ch (read-char))
(if (not (char=? ch #\x))
(begin
(display choice)
(loop)
)))))
这在技术上确实有效,但它会跳过迭代。例如:
Enter character: a
Enter character:
Enter character: s
在第二次迭代期间,我无法输入字符。我似乎无法确定问题所在。非常感谢任何帮助。
答案 0 :(得分:3)
问题在于您实际上正在阅读两个字符。你键入的那个,加上换行符。我试图尽可能地保留原始解决方案,这就是我想出来的:
(define getUserChar
(lambda ()
(define ch #\0)
(let loop ()
(display "Enter character: ")
(set! ch (string-ref (read-line) 0))
(if (not (char=? ch #\x))
(begin
(display ch)
(newline)
(loop))))))
恕我直言,一个更惯用的解决方案并不需要进行变异操作,我更喜欢这个:
(define (getUserChar)
(let loop ((ch #\0))
(unless (char=? ch #\x)
(display "Enter character: ")
(let ((ch (string-ref (read-line) 0)))
(display ch)
(newline)
(loop ch)))))
答案 1 :(得分:2)
这与你在循环的第一次迭代中输入两个字符的事实有关,即"a\n"
("a~n"
),这使得第二次迭代只需要{{1你和#\NewLine
一起作为角色输入了。
如果你想在get-line(R6RS)或#\a
(R7RS)的时候取一整行,或者看看buffer-mode(R6RS)并在开始之前啜饮这些字符新的迭代继续使用字符。