20

私のアプリで作業していると、Aeson が UTF8 入力をデコードしないという問題に遭遇しました。Parser ByteStringさらに深く掘り下げると、問題の原因と思われる Attoparsec に依存していることがわかりました。しかし、それは私がここで尋ねていることではありません。

JSONはバイナリファイルではなく、読み取り可能なテキストであり、UTF8文字が含まれている可能性があるため、ByteString私には明らかなように、適切な場所を使用している人を見たのはそれだけではありません。Text

だから私は何かが欠けていて、選択する正当な理由があるByteStringのか​​ 、Textそれともラテン語以外の文字セットをあまり気にしない大多数の人々によって引き起こされた悪いライブラリ設計の広範な現象なのか疑問に思っています.

4

1 に答える 1

22

あなたの問題は単なる誤解だと思います。

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.\"}"

print含む値を指定するStringと、Showインスタンス forCharが使用され、コード ポイントが 127 を超えるすべての文字がエスケープされます。必要なグリフを取得するにputStr[Ln]は、String.

したがってaeson、値自体が utf8 でエンコードされているため、予想されるように、utf8 でエンコードされた入力を適切にデコードしました。

encode = {-# SCC "encode" #-} encodeUtf8 . toLazyText . fromValue .
         {-# SCC "toJSON" #-} toJSON

では、なぜエンコーディングの最終ターゲットとデコーディングの開始点に and をaeson使用ByteStringしないのかという質問に。Text

それが適切なタイプだからです。エンコードされた値は、マシン間で移植可能に転送されることを目的としています。これは、バイトのストリームとして発生します (衒学的な気分であれば、オクテットです)。これはまさに がByteString提供するものであり、アプリケーション固有の方法で処理する必要がある一連のバイトです。の目的のためにaeson、バイトのストリームは utf-8 でエンコードされaeson、関数の入力が有効な utf-8 であると想定し、decodeその出力を有効な utf-8 としてエンコードします。

Text16 ビット エンディアンはエンディアンに依存するため、たとえば転送すると移植性の問題が発生Textします。マシン間のデータ交換には適切な形式ではありません。中間段階で使用するのに適した型であるため、エンコード時に (おそらくデコード時にも) を中間型としてaeson使用することに注意してください。Text

于 2012-12-29T17:21:54.497 に答える