Структуры

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

Пример объявления структуры:

// Структура с двумя полями
struct SomeStruct
{
    i32 x;
    f32 y;
}

struct EmptyStruct {} // дозволено объявить пустую структуру

// Структура с множеством полей различных типов, в т. ч. массивов и кортежей
struct ComplexStruct
{
    i32 x;
    [ f32, 16 ] arr;
    bool b;
    tup[ i32, f64 ] t;
}

Доступ к полям структур осуществляется с помощью оператора . с именем поля после него.

var SomeStruct mut s= zero_init;
s.x= 5;
s.y= 0.25f;
++s.x;
s.y= f32( s.x );

Функции структур

Структура может иметь функции внутри:

struct SomeStruct
{
    i32 x;
    f32 y;

    fn GetFieldCount() : size_type
    {
        return 2s;
    }
}

В данном примере объявлена обычная свободная функция, хоть она и расположена внутри структуры. Вызвать её можно следующим образом:

var SomeStruct s= zero_init;
auto x= s.GetFieldCount(); // Можно обратиться через переменную типа структуры
auto y= SomeStruct::GetFieldCount(); // А можно и напрямую, не создавая переменной типа структуры

Методы

Методы это функции структур и классов, первый параметр которых называется this. Тип у этого параметра не указывается - он неявно будет иметь тип структуры или класса, в котором объявлен метод. Перед this можно указать опциональный модификатор изменяемости mut или imut, смысл его аналогичен смыслу у других параметров. Параметр с именем this всегда должен быть первым параметром, нельзя называть другие параметры this. Методы можно вызывать только имея переменную типа структуры или класса. Внутри методов можно напрямую обращаться к полям, опуская параметр this.

Пример объявления методов:

struct Rect
{
    u32 w;
    u32 h;

    fn GetArea( this ) : u32
    {
        return w * h; // Поля "w" и "h" здесь относятся к "this"
    }

    // Изменяющий метод, в нём можно изменять поля "this"
    fn SetWidth( mut this, u32 new_w )
    {
        w= new_w;
    }

    fn SetHeight( mut this, u32 new_h )
    {
        this.h= new_h; // Можно обращаться к полям явно, используя "this"
    }
}

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

var Rect mut rect= zero_init;
rect.SetWidth( 5u );
rect.SetHeight( 8u );
auto area= rect.GetArea();

Параметр this по умолчанию является ссылочным. Но это можно изменить, добавив префикс byval. Тогда параметр this будет параметром-значением, аналогичным другим параметрам-значениям (не this) в любых других функциях.

struct S
{
    fn Foo( byval this ) : i32;
    fn Bar( byval mut this, i32 y ) : f32;
    fn Baz( byval imut this ) : bool;
}

При вызове метода с byval this значение структуры будет скопировано в значение аргумента или перемещено, если экземпляр структуры, использующийся для вызова, является непосредственным значением. Аргумент byval this будет разрушен (вызовется деструктор) при выходе из метода, если только он не был перемещён.

Прочее содержимое структур

Внутри структуры можно объявлять вложенные типы (структуры, классы, перечисления, псевдонимы), переменные. Получить доступ к ним можно будет так же, как и к элементам пространства имён.