Sized トレイトについて。
Sized トレイトは固定メモリサイズの型 (型から参照されるヒープ領域のサイズなどは除外) に自動で付加されるマーカートレイトである。一方、そうでない型は !Sized とマークされ、それらは DST (Dynamically Sized Type) と呼ばれる。
Sized になる型 u32 や Vec<u32> など)
&u32 や &str など)
[u32; 256] など)
Sized
!Sized になる型[u32] や [i32] など)
str のこと)
dyn Display など)
!Sized
関係各所で Sized に関する独特のルールがある。
rustdoc による API ドキュメントでは、型ごとに Auto Trait Implementations
の項目があり、自動実装されたトレイトが一覧できる。しかし、Sized は文書化されず、!Sized のみが文書化される。そのため、Sized かどうかは !Sized を探すことになる。
型パラメタは暗黙で Sized 境界を持つ。
暗黙の境界が不要な場合、?Sized を指定すればよい。
(後述の通り、トレイトの Self は例外。)
トレイトとその Self には特殊な扱いがされる。
Sized を指定する方法
Self は型パラメタの一種だが、トレイトの Self は暗黙の Sized 境界を持たない。
必要な場合、明示的に指定しなければならない。
指定方法は幾つかある。
where キーワードで Self: Sized とする方法。
その糖衣構文でトレイト宣言時に TraitName: Sized とする方法。
上記のどれかで Sized の代わりに、Sized を実装したトレイトを使う方法。
Sized を指定した場合
トレイトの Self における Sized は以下のように振る舞う。
引数や戻り値にて値渡しが可能になる。
※ これはトレイト以外と同じ。
トレイトの本体において、Self に Sized 境界を指定した場合。
そのトレイトのトレイトオブジェクトが作れなくなる。
トレイトのメソッドにおいて、Self に Sized 境界を指定した場合。
そのメソッドをトレイトオブジェクトから呼べなくなる。