什么是已弃用的 `Data.ByteString.Lazy.putStrLn` 的更安全和正确的替代方案,为什么?

What are the safer and correct alternatives to deprecated `Data.ByteString.Lazy.putStrLn` and why?

我想知道为什么 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 变体感觉有些危险。

已弃用的 putStrLn 假定它知道如何对 '\n' 字符进行编码。 None 您列出的其他函数假设有关编码的任何内容;他们只是交出你传递给他们的字节。 (确保这些字节对于您打算使用的编码是正确的是您的工作。)我同意 .Char8 模块不是那么热——它始终使用 latin1 编码,这并不'通过21世纪的考验。你考虑这个代码:

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

我不推荐这样做:它使您有机会在构造 myString 时使用的编码与 System.IO.putStrLn 正在使用的编码之间出现不匹配。相反,请确保 myString 最后有一个编码的换行符。