使用 putStr 和 getLine 的错误 IO 操作顺序 [英] Wrong IO actions order using putStr and getLine
问题描述
我有以下代码:
main = do
putStr "Test input : "
content <- getLine
putStrLn content
当我运行它(使用 runhaskell
)或编译它(ghc 6.10.4)时,结果是这样的:
When I run it (with runhaskell
) or compile it (ghc 6.10.4) the result is like this:
asd
Test input : asd
为什么 Test input : asd
打印在 asd
之后?
Why is Test input : asd
being printed after asd
?
在 http://learnyouahaskell.com/ 上的代码示例中,它使用了 putStr
,getLine
显示的输出与我的不同.当我使用 putStrLn
时,程序按预期工作(打印,然后提示,然后打印).
In the code sample on http://learnyouahaskell.com/, which uses putStr
, the getLine
's presented output is different than mine. When I use putStrLn
the program works as expected (print, then prompt, and print).
这是 ghc
中的一个错误,还是它应该工作的方式?
Is it a bug in ghc
, or it is the way that it should work?
推荐答案
这是因为 ghci 禁用了缓冲,而使用 ghc 编译的程序默认具有行缓冲.你可以通过运行这个来看到这一点:
This is because ghci disables buffering, while a program compiled with ghc has line buffering by default. You can see this by running this:
import System.IO
main = print =<< hGetBuffering stdout
在 ghci 中,您会看到 NoBuffering
而在 runghc 中,您会看到 LineBuffering
.由于在用户输入之后之前不会打印换行符,因此提示也不会.
In ghci you see NoBuffering
while with runghc you get LineBuffering
. Since the newline character doesn't print until after the user input, the prompt doesn't either.
通过在提示后添加 hFlush stdout
来修复它(或使用 hSetBuffering stdout NoBuffering
禁用缓冲,但这可能很糟糕).
Fix it by adding hFlush stdout
after your prompt (or disable buffering with hSetBuffering stdout NoBuffering
, but that’s probably bad).
这篇关于使用 putStr 和 getLine 的错误 IO 操作顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!