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

Структура

Обзор

Структуры в языке Wave являются основным синтаксическим элементом для объявления пользовательских типов данных. Использование структур позволяет объединить значения разных типов в одну логическую единицу, что обеспечивает ясное и безопасное моделирование сложных структур данных.

Структуры Wave работают как типы значений. Все поля должны иметь явный тип, и при создании экземпляра структуры все поля должны быть инициализированы. Эти правила гарантируют, что состояние структуры всегда будет полным и предсказуемым.

Синтаксис объявления структур

Структура объявляется с помощью ключевого слова struct. Имена структур следуют нотации PascalCase, и в теле структуры можно определить одно или более полей.

Поля объявляются в формате имя: тип;, и каждая декларация поля должна оканчиваться точкой с запятой.

struct Box {
size: i32;
weight: f32;
}

Порядок записанных полей при объявлении структуры соответствует порядку размещения в памяти. Внутри структуры разрешены только объявления полей, функции или методы не могут быть включены. Логика работы определяется отдельно от структуры.

Синтаксис создания структуры

Структуры создаются в виде литералов с использованием имени структуры. Литерал структур выглядит как StructName { поле: значение; ... записываются в виде }.

var b: Box = Box {
size: 42;
weight: 10.5;
};

При создании структуры необходимо инициализировать все заданные поля, и компилятор выдаст ошибку при пропуске любого из них.

Порядок инициализации полей не обязательно должен совпадать с порядком объявления структуры, но тип значения для каждого поля должен точно соответствовать определённому в структуре типу. При инициализации полей структур в Wave не допускаются неявные преобразования типов.


Синтаксис доступа к полям структуры

Поля структуры доступны через точечную нотацию. Для чтения и записи полей используется одинаковый синтаксис.

println("Size: {}", b.size);
println("Weight: {}", b.weight);

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


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

Язык Wave не позволяет напрямую определять методы внутри структуры. Вместо этого используется ключевое слово прото для объявления множества методов, связанных со структурой.

Блок proto является областей функций, принадлежащих конкретной структуре. Функции, определенные в этом блоке, используются как методы этой структуры.

Методы принимают экземпляр структуры в качестве первого параметра self. self предполагает значение всей структуры, передаваемое как копия.

proto Box {
fun print(self) {
println("size={}, weight={}", self.size, self.weight);
}

fun added_size(self, x: i32) -> i32 {
return self.size + x;
}
}

Блоки прото не обязаны находиться в том же файле, что и объявление структуры, но несколько блоков прото могут использоваться для определения методов для одной и той же структуры.

Методы вызываются с использованием синтаксиса точки, аналогично общему вызову функции.

b.print();
var n: i32 = b.added_size(5);

Использование структуры в качестве аргумента функции

Структуры обрабатываются как копии при передаче в качестве аргументов функции. Изменения в полях структуры внутри функции не влияют на экземпляр структуры вызывающей стороны.

fun calc(box: Box) -> i32 {
return box.size * 2;
}

Так же как и в случае с аргументами, возвращение структуры функции сопровождается копированием значений. Такая работа обеспечивает неизменность структур и предсказуемый поток данных.


Вложенные структуры

В Wave можно использовать другую структуру в качестве типа поля структуры. Поскольку структуры являются полными типами, их можно свободно вкладывать друг в друга.

struct Position {
x: i32;
y: i32;
}

struct Player {
name: str;
pos: Position;
}

Доступ к полям вложенной структуры осуществляется с использованием цепочки точечной нотации.

var p: Player = Player {
name: "Alice";
pos: Position { x: 10; y: 20; };
};

println("Player X: {}", p.pos.x);
println("Player Y: {}", p.pos.y);

Литералы структур могут содержать другие литералы структур, и при этом сохраняются все правила инициализации полей.


Массив структур

Структуры могут быть использованы как тип элементов массива. В Wave используется синтаксис массива array<тип, длина>, а структуры могут быть указаны как типы напрямую.

var players: array<Player, 3> = [
Player { name: "A"; pos: Position { x: 1; y: 2; }; },
Player { name: "B"; pos: Position { x: 3; y: 4; }; },
Player { name: "C"; pos: Position { x: 5; y: 6; }; }
];

При доступе к элементу массива структур сначала используется индекс массива, затем — точечная нотация для доступа к внутренним полям структуры.

println("Second Player X: {}", players[1].pos.x);

Возможность базовых операций со структурами

Поскольку структуры в Wave являются пользовательскими типами, они не задействуются автоматически в арифметических или сравнительных операциях.

Если требуется сравнение на равенство, сортировка, хеширование, числовые операции с структурами, их необходимо явно определить через блок прото. Wave не предоставляет неявных операторов для структур и руководствуется принципом явного определения всех операций.