Kompilator nie jest zbyt inteligentny, jeśli chodzi o optymalizację układu enum
s dla miejsca. Biorąc pod uwagę:
enum Option<T> { None, Some(T) }
enum Weird<T> { Nil, NotNil { x: int, y: T } }
enum Foo { A, B, C }
Jest naprawdę tylko jeden przypadek kompilator uzna:
Option
-jak ENUM: jeden wariant przeprowadzania żadnych danych („sygnalnych”), jeden wariant zawierający dokładnie jeden punkt odniesienia. W przypadku użycia ze wskaźnikiem, o którym wiadomo, że nigdy nie ma wartości null (obecnie tylko odniesienia i Box<T>
) reprezentacja będzie taka jak pojedynczego wskaźnika, null oznaczający wariant zerowy. W specjalnym przypadku, Weird
będzie poddawany takiej samej obróbce, ale wartość pola y
będzie używana do określenia, który wariant reprezentuje wartość.
Poza tym istnieje wiele, wiele możliwych optymalizacji, ale kompilator ich jeszcze nie robi. W szczególności Twój przypadek będzie , a nie reprezentowany jako pojedynczy bajt. Dla pojedynczego wyliczenia, nie biorąc pod uwagę zagnieżdżonego przypadku, będzie on reprezentowany jako najmniejsza liczba całkowita, jaką może.
The rustc z pewnością zna rozmiar wariantów enum. W rzeczywistości istnieje [lint] (https://github.com/rust-lang/rust/pull/14300), który ostrzega, gdy jeden rozmiar wariantu jest znacznie większy niż inne. Ale nie wiem, czy 'Opcja' w twoim pytaniu zostanie zoptymalizowana do jednego bajtu czy nie. –
edwardw
Najprawdopodobniej jest zoptymalizowany pod kątem wskaźników takich jak "Opcja <~T>". –
[# 14540] (https://github.com/rust-lang/rust/issues/14540) zostało dodane chwilę temu o dodaniu tej optymalizacji do kompilatora (ponieważ jest to całkowicie dozwolone przez język). – huon