サイズがゼロの型は ZST (Zero Sized Types) と呼ばれる。
以下の型は ZST として扱われる。
とりあえず ZST を利用したい場合、空のタプル ()
が使われる事が多い。
より具体的な方法については『空のタプル (ユニット)』を参照。
おそらく滅多に使われない機能だと思われるが、気付いたので一応メモしておく。
ZST の読書時のサイズはゼロだが、アドレスは用意される場合がある。
ZST を通常の変数として用意した場合、アドレスを識別するための最低限度のメモリ領域が確保される。
fn main() {
let zst1 = Zst;
let zst2 = Zst;
dbg!(&zst1 as *const _);
dbg!(&zst2 as *const _);
}
pub struct Zst;
[src\main.rs:4] &zst1 as *const _ = 0x000000c08ecfeb70 [src\main.rs:5] &zst2 as *const _ = 0x000000c08ecfeb78
なお、配列では要素ごとのアドレスが重複する。
fn main() {
let arr = [Zst, Zst];
dbg!(&arr[0] as *const _);
dbg!(&arr[1] as *const _);
}
pub struct Zst;
[src\main.rs:3] &arr[0] as *const _ = 0x00000089702fec08 [src\main.rs:4] &arr[1] as *const _ = 0x00000089702fec08
Box
の場合
Box
と ZST の組合せは何の役にも立たない。
アドレスを識別するためのメモリすら用意されない。
fn main() {
let zst1 = Box::new(Zst);
let zst2 = Box::new(Zst);
dbg!(Box::into_raw(zst1));
dbg!(Box::into_raw(zst2));
}
pub struct Zst;
[src\main.rs:4] Box::into_raw(zst1) = 0x0000000000000001 [src\main.rs:5] Box::into_raw(zst2) = 0x0000000000000001
Vec
の場合
Vec
と ZST の組合せも何の役にも立たない。
各要素ごとにも全体でもメモリは用意されない。
fn main() {
let vec1 = vec![Zst];
let vec2 = vec![Zst];
dbg!(&vec1.as_slice()[0] as *const _);
dbg!(&vec2.as_slice()[0] as *const _);
}
pub struct Zst;
[src\main.rs:4] &vec1.as_slice()[0] as *const _ = 0x0000000000000001 [src\main.rs:5] &vec2.as_slice()[0] as *const _ = 0x0000000000000001