为什么图书馆设计师使用ByteString,其中Text似乎合适?

Nik*_*kov 19 haskell attoparsec aeson

在我的应用程序上工作我偶然发现Aeson无法解码UTF8输入的问题.深入挖掘我发现它依赖于Parser ByteStringAttoparsec,这似乎是问题的根源.但实际上并不是我在这里问的问题.

事情是它不是我见过人们使用的唯一地方ByteString,因为对我来说似乎很明显,只是Text合适的,因为JSON不是一些二进制文件,它是一个可读的文本,它可能很好地包含UTF8字符.

所以我想知道我是否遗漏了某些东西并且有正当理由可以选择ByteString,Text或者这只是一种普遍存在的错误的图书馆设计现象,这是因为大多数人对拉丁语中任何其他角色的关注较少.

Dan*_*her 21

我认为你的问题只是一个误解.

Prelude> print "???? ????? ???."
"\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076."
Prelude> putStrLn "\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076."
???? ????? ???.
Prelude> "{\"a\": \"???? ????? ???.\"}"
"{\"a\": \"\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076.\"}"
Run Code Online (Sandbox Code Playgroud)

当您print使用包含a的值时String,将使用Show实例for Char,并且该代码点的所有字符都会超过127.要获取所需的字形,您需要putStr[Ln]使用String.

所以aeson正确解码了utf8编码的输入,正如所期望的那样,因为它对值本身进行了utf8编码:

encode = {-# SCC "encode" #-} encodeUtf8 . toLazyText . fromValue .
         {-# SCC "toJSON" #-} toJSON
Run Code Online (Sandbox Code Playgroud)

所以问题为什么aeson使用ByteString而不是Text编码的最终目标和解码的起点.

因为那是合适的类型.编码值旨在在机器之间移植.这发生在一个字节流(八位字节,如果我们处于迂腐的情绪).这正是ByteString提供的,然后必须以特定于应用程序的方式处理一系列字节.出于此目的aeson,字节流应以utf-8编码,并aeson假定decode函数的输入有效utf-8,并将其输出编码为有效的utf-8.

传输例如Text会遇到可移植性问题,因为16位编码取决于字节顺序,因此Text不适合在机器之间交换数据.注意,在编码时(并且可能在解码时)aeson使用Text作为中间类型,因为这是在中间阶段使用的适当类型.

  • 我不明白为什么解析器/发射器负责选择/ my/network传输的格式.它解析文本数据,Data.Text具有制作和接收任何UTF编码的功能,而Aeson仅限于解析UTF8编码的字节串. (2认同)