Rustのstr型
でもstrという型はないよね?なんで?
この辺にちゃんと実装がある
GPT-4.icon
はい、&strの&は参照を表す記号であり、他の&T型と同じ意味を持っています。しかし、strという型が存在しないように見える理由について説明します。
---
strは存在しますが、特別な型です
Rustにはstrという型があります。ただし、この型はサイズがコンパイル時に決まらない型(DST)であるため、通常そのまま使うことはできません。 strはDynamically Sized Type:
str自体はメモリ上でどれくらいの長さを持つかがコンパイル時に分からないため、スタック上に直接格納することができません。
代わりに、参照型(&str)や所有型(Box<str>)を通じて使われます。
コンパイラはstr単体では許可しませんが、&strやBox<str>を使うことで、そのサイズを間接的に扱えるようにしています。
---
&strが使える理由: FATポインタ
Rustでは、&strは「文字列スライス」を意味し、通常の参照型(&T)と同様に動作します。ただし、strがサイズ不定の型であるため、&strは単なるポインタではなくFATポインタと呼ばれる仕組みを利用します。
FATポインタ:
&strは、以下の2つの情報を保持しています:
1. データへのポインタ: 文字列データの開始位置。
2. 長さ: 文字列データのバイト長。
この構造により、strのサイズが不明であっても&strを使って文字列スライスを操作できます。
FATポインタのイメージ
code:_
&str:
+---------------------+
| データへのポインタ |
+---------------------+
| 長さ(バイト数) |
+---------------------+
なぜstr単体では使えないのか
Rustではすべての型がコンパイル時にサイズ(Sized trait)を持つ必要があります。ただし、strはDSTであるため、以下のように直接使用することはできません。 code:rs
fn main() {
let s: str; // エラー: Sizedでない型はそのまま使えません
}
strを使いたい場合は、常に&strやBox<str>のようにサイズを持つ参照やヒープ型で間接的に扱います。
---
Stringは、UTF-8エンコードされた文字列をヒープ上で管理する所有型です。
内部的には、ヒープに格納されたstrデータを指しており、以下の情報を持っています:
1. データへのポインタ
2. 長さ(バイト数)
3. 容量(capacity)
このように、Stringはstrをヒープで管理するためのラッパーです。