【问题标题】:What is the best way to convert String to ByteString将 String 转换为 ByteString 的最佳方法是什么
【发布时间】:2010-07-12 20:35:40
【问题描述】:

在 Haskell 中将 String 转换为 ByteString 的最佳方法是什么?

我对这个问题的直觉反应是

import qualified Data.ByteString as B
import Data.Char (ord)

packStr = B.pack . map (fromIntegral . ord)

但这似乎并不令人满意。

【问题讨论】:

  • 现代:您通常应该将[Char] 转换为Text 和[Word8] 转换为ByteString。它仍然是pack :)
  • 将 Unicode 转换为字节涉及使用 Unicode 编码。使用pack 更类似于不安全的演员表。

标签: string haskell bytestring


【解决方案1】:

这是我的 Haskell 字符串/文本/字节字符串严格/延迟转换的备忘单,假设所需的编码是 UTF-8。 Data.Text.Encoding 库有其他可用的编码。

请确保不写(使用 OverloadedStrings):

lazyByteString :: BL.ByteString
lazyByteString = "lazyByteString ä ß" -- BAD!

这将以一种意想不到的方式进行编码。试试

lazyByteString = BLU.fromString "lazyByteString ä ß" -- good

改为。

'Text' 类型的字符串文字在编码方面工作正常。

备忘单:

import Data.ByteString.Lazy as BL
import Data.ByteString as BS
import Data.Text as TS
import Data.Text.Lazy as TL
import Data.ByteString.Lazy.UTF8 as BLU -- from utf8-string
import Data.ByteString.UTF8 as BSU      -- from utf8-string
import Data.Text.Encoding as TSE
import Data.Text.Lazy.Encoding as TLE

-- String <-> ByteString

BLU.toString   :: BL.ByteString -> String
BLU.fromString :: String -> BL.ByteString
BSU.toString   :: BS.ByteString -> String
BSU.fromString :: String -> BS.ByteString

-- String <-> Text

TL.unpack :: TL.Text -> String
TL.pack   :: String -> TL.Text
TS.unpack :: TS.Text -> String
TS.pack   :: String -> TS.Text

-- ByteString <-> Text

TLE.encodeUtf8 :: TL.Text -> BL.ByteString
TLE.decodeUtf8 :: BL.ByteString -> TL.Text
TSE.encodeUtf8 :: TS.Text -> BS.ByteString
TSE.decodeUtf8 :: BS.ByteString -> TS.Text

-- Lazy <-> Strict

BL.fromStrict :: BS.ByteString -> BL.ByteString
BL.toStrict   :: BL.ByteString -> BS.ByteString
TL.fromStrict :: TS.Text -> TL.Text
TL.toStrict   :: TL.Text -> TS.Text

请 +1 Peaker 的回答,因为他正确处理编码。

【讨论】:

  • 我花了一点时间才发现Data.ByteString.UTF8 在包utf8-string 中。
  • 我还必须将- utf8-string 添加到我的Package.yaml
【解决方案2】:

Data.ByteString.UTF8.fromString 也很有用。 Char8 版本将失去 unicode-ness,UTF8 将生成 UTF8 编码的 ByteString。您必须选择其中之一。

【讨论】:

  • 如果出现问题:Hoogle 没有找到此函数,因为它仅索引一小组库(GHC 附带的库)。扩展由 Hoogle 索引的库集已多次出现,但我认为由于 Hoogle 开发人员 (Neil) 的时间限制,尚未完成。仅供参考,这里讨论的函数来自 utf8-string 包。
  • @TomMD:Hayo 解决了这个问题:holumbus.fh-wedel.de/hayoo/…
  • @peaker:不令我满意。 Hayoo 在类型搜索方面做得很差,尤其是当类型是通用类型或多态类型时。
【解决方案3】:

一种安全的方法是对 unicode 字符串进行编码:

import qualified Data.ByteString as B
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)

packStr'' :: String -> B.ByteString
packStr'' = encodeUtf8 . T.pack

关于其他答案:Data.ByteString.Char8.pack 实际上与问题中的版本相同,不太可能是您想要的:

import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as C
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
import Data.Char (ord)

packStr, packStr', packStr'' :: String -> B.ByteString
packStr   = B.pack . map (fromIntegral . ord)
packStr'  = C.pack
packStr'' = encodeUtf8 . T.pack

*Main> packStr "hellö♥"
"hell\246e"
*Main> packStr' "hellö♥"
"hell\246e"
*Main> packStr'' "hellö♥"
"hell\195\182\226\153\165"

Data.ByteString.UTF8.fromString 可以,但需要 utf8-string 包,而 Data.Text.Encoding 是 Haskell 平台自带的。

【讨论】:

  • Codec.Binary.UTF8.String也可以用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2016-05-29
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多