Перейти к основному содержимому

Перечисления (enum) и псевдонимы типов (type alias)

Wave, сохраняя типовую систему, схожую с C, поддерживает псевдонимы типов и перечисления на основе целых чисел для улучшения читаемости и стабильности ABI.


Псевдонимы типов (type alias)

Обзор

Ключевое слово type присваивает существующему типу новое имя. Это не создание нового типа, а полное равенство (alias).

type MyInt = i32;

В приведённом объявлении МойИнт полностью соответствует типу i32.


Особенности

  • Без накладных расходов при выполнении
  • Полная идентичность в рамках ABI
  • Существующий только на этапе компиляции
  • Может использоваться в качестве типа репрезентации enum

Пример использования

type Size = i64;
type Index = u32;

fun add(a: Size, b: Size) -> Size {
return a + b;
}

Эквивалентность типов

type A = i32;
type B = A;

fun f(x: i32) -> i32 { return x; }

fun main() {
var v: B = 10;
f(v); // OK
}

Тип — это не новый тип, а тип с другим именем.


Перечисление (enum)

Обзор

Перечисления в Wave основаны на целых числах. Все перечисления должны иметь тип представления его repr.

enum ShaderUniformType -> i32 {
A = 0,
B,
C = 10,
D
}

тип repr

Использование -> i32 показывает, как тип перечисления будет выражаться.

Допустимые типы представления:

  • i8, i16, i32, i64
  • i8, i16, i32, i64
  • type alias для этого типа
type MyInt = i32;

enum Example -> MyInt {
X,
Y
}

Правило назначения значений

  • Используйте указанное значение, если оно явно указано.
  • Если нет, то предыдущее значение + 1
  • Если нет первого значения, начинайте с 0
enum E -> i32 {
A, // 0
B, // 1
C = 10, // 10
D // 11
}

Перечисление является типом значения

Перечисление — это целочисленное значение, которое можно свободно использовать как аргумент или возвращаемое значение функции.

fun f(t: ShaderUniformType) -> i32 {
return t;
}

Использовать как константу

Варианты перечисления являются константами времени компиляции.

const X: i32 = B;
const Y: ShaderUniformType = D;

Пример использования

type MyInt = i32;

enum ShaderUniformType -> MyInt {
A = 0,
B,
C = 10,
D
}

const X: MyInt = 123;
const Y: MyInt = B;
const Z: ShaderUniformType = D;

fun f(t: ShaderUniformType) -> MyInt {
return t;
}

fun g(v: MyInt) -> MyInt {
return v;
}

fun main() {
println("{}", f(A)); // 0
println("{}", f(B)); // 1
println("{}", f(C)); // 10
println("{}", f(D)); // 11

println("{}", g(X)); // 123
println("{}", g(Y)); // 1
println("{}", f(Z)); // 11
}