弃用的“Data.ByteString.Lazy.putStrLn”有哪些更安全和正确的替代方法?为什么?

时间:2015-03-10 13:45:26

标签: string haskell unicode io newline

我想知道为什么Data.ByteString.Lazy.putStrLn被弃用了,但是 Data.ByteString.Lazy.putStrData.ByteString.Lazy.hPutStr是。{ 不?

-- | A synonym for @hPut@, for compatibility
--
hPutStr :: Handle -> ByteString -> IO ()
hPutStr = hPut

-- | Write a ByteString to stdout
putStr :: ByteString -> IO ()
putStr = hPut stdout

-- | Write a ByteString to stdout, appending a newline byte
--
putStrLn :: ByteString -> IO ()
putStrLn ps = hPut stdout ps >> hPut stdout (singleton 0x0a)

{-# DEPRECATED putStrLn
"Use Data.ByteString.Lazy.Char8.putStrLn instead. (Functions that rely on ASCII encodings belong in Data.ByteString.Lazy.Char8)"
  #-}

-- | The interact function takes a function of type @ByteString -> ByteString@
-- as its argument. The entire input from the standard input device is passed
-- to this function as its argument, and the resulting string is output on the
-- standard output device.

我认为那是因为字符串中存储的字符 如果您未指定编码,则无法正确输出 明确。

但是这应该适用于所有这些功能。

现在我怀疑只有换行符才是原因 考虑到这个功能不好。

然后,我可以简单地做

Data.ByteString.Lazy.putStr myString >> System.IO.putStrLn ""

并且在输出时不会丢失信息并且感到安全吗?

.Char8变种感觉有些危险。

1 个答案:

答案 0 :(得分:2)

不推荐使用的putStrLn假定它知道如何编码'\n'字符。您列出的其他任何功能都不会假设编码;他们只是将你传递的字节移交给他们。 (确保这些字节对于您打算使用的编码是正确的,这是您的工作。)我同意.Char8模块不是那么热 - 它始终使用latin1编码,这不是没有通过21世纪的考验。你考虑这个代码:

ByteString.putStr myString >> System.IO.putStrLn ""

我不建议这样做:它让您有机会在用于构建myString的编码与System.IO.putStrLn正在使用的编码之间出现不匹配。相反,请确保myString最后在其中包含已编码的换行符。