Rustのstr型
&str
の
&
って、
&T型の
&
と同じ意味?
でも str
という型はないよね?なんで?
この辺にちゃんと実装がある
はい、 &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ポインタのイメージ
_&str:
+---------------------+
| データへのポインタ |
+---------------------+
| 長さ(バイト数) |
+---------------------+
なぜ str
単体では使えないのか
Rustではすべての型がコンパイル時にサイズ(
Sized trait)を持つ必要があります。ただし、
str
はDSTであるため、以下のように直接使用することはできません。
rsfn main() {
let s: str; // エラー: Sizedでない型はそのまま使えません
}
str
を使いたい場合は、常に &str
や Box<str>
のようにサイズを持つ参照やヒープ型で間接的に扱います。
---
String
は、UTF-8エンコードされた文字列をヒープ上で管理する所有型です。
内部的には、ヒープに格納された str
データを指しており、以下の情報を持っています:
1. データへのポインタ
2. 長さ(バイト数)
3. 容量(capacity)
このように、 String
は str
をヒープで管理するためのラッパーです。