Rustのchar型とString型の違いを理解する

エンジニア歴3年でpython以外触ったことのないので、Rustを始めてみました。

しかし、char型とString型の違いがわからず、まるでコードが書けません。とりあえず、[プログラミングRust](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0Rust-Jim-Blandy/dp/4873118557)(notアフィリンク)という本を買ったので、それを読みながら理解したいと思います。

# UnicodeとUTF-8
プログラミングRustを読んでいたら、UnicodeとUTF-8いう単語が出てきましたが、まるで理解せずにここまで生きてきました。まずはこの区別をつけないと、先に進めない気がするので調べます。

## [Unicode](https://ja.wikipedia.org/wiki/Unicode)
Wikipedia:
>
「Unicode（ユニコード）は、符号化文字集合や文字符号化方式などを定めた、文字コードの業界規格である。文字集合（文字セット）が単一の大規模文字セットであること（「Uni」という名はそれに由来する）などが特徴である。 」

知らない単語が多すぎて1mmも理解できません。
符号化文字集合も文字符号化方式も文字コードもわからないので、それぞれ調べて行きます。

## [文字コード](https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89)
>
「文字コード（もじコード）とはコンピュータ上で文字（キャラクタ (コンピュータ)）を利用する目的で各文字に割り当てられるバイト表現。もしくは、バイト表現と文字の対応関係（文字コード体系）のことを指して「文字コード」と呼ぶことも多い。本記事では主に後者について記述する。」

バイト表現もしくは、バイト表現と文字の対応関係のようです。

## [文字集合](https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E9%9B%86%E5%90%88)
文字集合のページに符号化文字集合の説明があったので、まずは文字集合から見ていきます。

>
「文字集合（もじしゅうごう、英: character set）は、文字（キャラクタ (コンピュータ)）をその要素（「元」）とする集合である。文字セットという場合もある。例えば、「全てのアルファベット」(a, b, c, ..., z, A, B, C, ..., Z)というのもひとつの文字集合であるし、「全てのひらがな」(あ, い, う, ..., ん)というのもまた、ひとつの文字集合である。 」

...文字の集合ですね。じゃあ符号化文字集合は？

### 符号化文字集合
>
「文字集合を定義しその集合内の各文字に一意の符号化表現を関連付ける規則を符号化文字集合と言う。符号化文字集合には、例えばJIS X 0201、JIS X 0208、ISO/IEC 10646(UCS-2, UCS-4)等がある。標準や規格によって用語に違いがあり次のように定義されている。 」

文字集合の要素である文字たちに、ひとつひとつ符号化表現を関連付けたもののようです。

## [文字符号化方式](https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E7%AC%A6%E5%8F%B7%E5%8C%96%E6%96%B9%E5%BC%8F)
>
「文字符号化方式（もじふごうかほうしき、英: character encoding scheme、CES）とは、符号化文字集合で文字に対応付けた非負整数値を、実際にコンピュータが利用できるデータ列（通常、バイト列）に変換する符号化方式。
文字符号化体系、文字符号化スキーム (CCS) とも言う。文字について述べていることが明確なときは、単に符号化方式、またIBMの用語ではコード化体系 (ES) などとも言う。
この用語はUnicodeやIETFの標準などで用いているが、ISO/IECやJISの標準では用いず「符号化文字集合の構造」あるいは「文字符号の構造及び拡張法」として扱われている。この用語の定義は、世界の文字コード規格とは必ずしも合致しないことがある。 」

符号化文字の符号部分をさらに、コンピュータが利用できるバイト列に変換する方式のようです。
符号化文字集合の「符号」は非負整数値で、文字符号化集合の「符号」はバイト列、ということでしょうか。

## [コードポイント(符号点)](https://ja.wikipedia.org/wiki/%E7%AC%A6%E5%8F%B7%E7%82%B9)
>
符号点（ふごうてん）は、符号化文字集合内の、文字を割り当てうる個々の点。コードポイント (code point)。...中略...Unicodeのように符号空間が1次元の場合は、長さ1の整数列、つまり、1つの整数となる。

コードポイントという単語もよく聞くので調べてみました。符号化文字集合の符号部分をコードポイントと呼ぶようです。


ここまでひとまずまとめてみると、Unicodeとは、「文字に対応する非負整数値(コードポイント)と、さらにそのコードポイントに対応するバイト列が定められた、文字の集合」という感じでひとまず理解することにします。

## [UTF-8](https://ja.wikipedia.org/wiki/UTF-8)
>
「UTF-8（ユーティーエフはち、ユーティーエフエイト）はISO/IEC 10646 (UCS) とUnicodeで使える8ビット符号単位の文字符号化形式及び文字符号化スキーム。 」

`文字符号化形式及び文字符号化スキーム`は、先程調べた`文字符号化形式`と同じなので、コードポイントをバイト列に変換する規則です。ということは、UTF-8は文字符号化形式の中の一つということでしょうか。どうやら文字符号化形式自体がこの世にたくさんありそうなニュアンスなので、よく聞くUTF-16とかも文字符号化形式である気がします。

`ビット`や`符号`の意味もわからないという事実に気づいたので、それも調べておきます。

## [符号](https://ja.wikipedia.org/wiki/%E7%AC%A6%E5%8F%B7)
>
符号理論において、符号（ふごう）またはコード（英: code）とは、シンボルの集合S, Xがあるとき、Sに含まれるシンボルのあらゆる系列から、Xに含まれるシンボルの系列への写像のことである。Sを情報源アルファベット、Xを符号アルファベットという。すなわち符号とは、情報の断片（例えば、文字、語、句、ジェスチャーなど）を別の形態や表現へ（ある記号から別の記号へ）変換する規則であり、変換先は必ずしも同種のものとは限らない。 

とある情報を別の形態に変換する規則のようです。今までつかっていた符号化という言葉も、記号を別の記号に変換するという意味だったのでしょう。同じ符号化という言葉で、異なる変換が行われていたのも納得です。

## [ビット](http://yougo.ascii.jp/caltar/%E3%83%93%E3%83%83%E3%83%88)
ASCII.jpデジタル用語辞典:
>
コンピューターの中で扱うデータの最小単位。1ビットで2進数の1桁が0か1かを表せる。文字や画像など、すべての情報はビットの組み合わせで表現されている。ただし、実際にコンピューターが扱う情報の単位は8ビットを1組にしたバイト単位で表すことが多い。1バイト＝8ビットである。 

0か1のことですね。ついでにバイトが8ビットのことだということもわかりました。なんか昔に調べた気もします。

UTF-8とUTF-16は、ビット数が関係しているのでしょうか？
話がそれてきたのと、理解が追いつかないので、ここまでの知識で一旦、RustのStringとCharの話に戻ってみましょう。

# RustにおけるString型やchar型と、文字コードの関係
Char (プログラミングRust17.2)
> Rust の char は Unicode のコードポイントを保持する 32 ビットの値だ。

String (プログラミングRust17.3)
> Rust の String 型と str 型は、整形式な UTF-8 を保持していることが保証されている。` 

とのことなので、Char=コードポイント、String=UTF-8のバイト列、となるようです。...

--- 追記start2/5 21:00 ---
と、思っていたのですが、どうやらCharの説明が正確ではないようで、Rustの[ドキュメント](https://doc.rust-lang.org/std/primitive.char.html)に
>char is a 'Unicode scalar value', which is similar to, but not the same as, a 'Unicode code point'.

とあるため、Char型はコードポイントではなくunicode salar valueというもののようです。書籍プログラミングRustが、間違っていたと思われます。
(κeenさん、コメントいただきありがとうございました。)
--- 追記end ---

どこでどう使い分ければよいのかまるでわかりませんが、とりあえずこの知識でコーディングしてみます。