DSTは単独で扱えない
[T]
や str
が単独で使えない理由
Rustでは、コンパイル時にサイズが確定しない型は「ダイナミックサイズ型(DST: Dynamically Sized Type)」と呼ばれます。このような型(例えば [T]
や str
)は、スタック上で単独の値として扱うことができません。その理由を詳しく説明します。
---
1. スタックとサイズの関係
Rustでは、スタックフレームにデータを配置する際に、そのデータのサイズがコンパイル時に完全に分かっている必要があります。これは以下の理由によります:
1. 効率性:
スタックは高速で固定長のメモリ領域であるため、データのサイズが決まっていれば、スタック上で効率的にメモリ操作が可能です。
2. 型安全性:
Rustはコンパイル時に型とメモリサイズの一貫性を確認します。サイズが動的であると、型安全性が保証できなくなります。
2. [T]
や str
がサイズ不定である理由
[T]
の場合
[T]
は要素数が不明であるため、コンパイル時にデータ全体のサイズが確定しません。
例えば、 [i32]
という型では「i32の配列」であることは分かりますが、「何個の要素が含まれているか」は情報として欠けています。
str
の場合
str
はUTF-8エンコーディングの文字列型ですが、文字列の長さ(バイト数)は動的に変わるため、 str
型そのものもサイズが不定です。
---
3. サイズ不定型(DST)をスタック上で扱えない理由
Rustでは、サイズ不定型(DST)は単独で値として存在できないという制約があります。その理由は以下の通りです:
1. サイズが不定の型は、メモリ領域を確保できない
例えば、 [i32]
型をスタック上で直接扱おうとすると、「要素数が不明」のため、どれだけのメモリを確保するべきか分かりません。
2. 参照やポインタでサイズを補完する必要がある
&[i32]
のような参照では、以下の情報がセットで保持されます:
データの開始位置(ポインタ)
要素数(長さ)
これにより、データのサイズが不定でも、間接的にその内容を扱うことが可能になります。
わかりやし〜〜


---
5. &[T]
や Box<[T]>
の仕組み
スライス( [T]
)を扱う場合、以下のような間接的な形で使われます:
1. &[T]
(参照型)
&[T]
はメモリ上に以下の情報を持っています:
データの開始位置(ポインタ)
長さ(usize型)
この情報を用いて、データがどこから始まり、何個の要素が含まれているかを把握します。
2. Box<[T]>
(スマートポインタ型)
Box<[T]>
は [T]
をヒープ上に確保し、そのポインタを保持します。
ヒープ領域では、動的なサイズのデータを扱えるため、 [T]
をヒープに置くことで動的配列のように利用可能になります。
7. 具体例で理解する
配列とスライスの違い
rustfn main() {
let array: [i32; 3] = [1, 2, 3]; // 配列 (固定長、サイズが既知)
let slice: &[i32] = &array; // スライス (動的長、参照)
println!("{:?}", slice); // [1, 2, 3]
}
この場合、 array
はスタック上に直接存在します。一方、 slice
は array
の参照と長さを持つ構造体のようなものです。