查看 traceIO
的描述,我觉得它的作用正是hPutStrLn stderr
做。但是,当我查看它的源代码时:
traceIO :: String -> IO ()
traceIO msg = do
withCString "%s\n" $ \cfmt -> do
-- NB: debugBelch can't deal with null bytes, so filter them
-- out so we don't accidentally truncate the message. See Trac #9395
let (nulls, msg') = partition (=='\0') msg
withCString msg' $ \cmsg ->
debugBelch cfmt cmsg
when (not (null nulls)) $
withCString "WARNING: previous trace message had null bytes" $ \cmsg ->
debugBelch cfmt cmsg
它似乎使用了一个名为
debugBelch
的外部例程。 ,我没有找到任何关于它的文档。那么traceIO
是什么意思? hPutStrLn stderr
做不到的事?
最佳答案
我能想到的一件事是,它可以确保字符串作为一个单元打印,内部没有任何其他跟踪消息。事实上,一个实验似乎证实了这一点:
Prelude Debug.Trace System.IO> traceIO $ "1" ++ trace "2" "3"
2
13
Prelude Debug.Trace System.IO> hPutStrLn stderr $ "1" ++ trace "2" "3"
12
3
另一个区别是它似乎删除了无法安全打印到 stderr 的字符:
Prelude Debug.Trace System.IO> hPutStrLn stderr "\9731"
*** Exception: <stderr>: hPutChar: invalid argument (invalid character)
Prelude Debug.Trace System.IO> traceIO "\9731"
Prelude Debug.Trace System.IO>
正如@dfeuer 提醒我的那样,这些功能都不是不可能用 Haskell 编写的。所以决定因素可能是:
debugBelch
已经是预定义的 C 函数,使用了 all over the place在 GHC 的运行时系统中,它是用 C 和 C--而不是 Haskell 编写的。
关于debugging - `traceIO` 和 `hPutStrLn stderr` 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33059675/