Структуры

структура Точка
    целое х;
    целое у;

    функция сумма_координат(): целое
        вернуть это.х + это.у;
    конец
конец
  • Поля объявляются как обычные переменные, без значений по умолчанию
  • Методы — обычные функции внутри тела структуры
  • это — ссылка на текущий экземпляр внутри метода (аналог

self/this в других языках)

  • Конструктор генерируется автоматически, по всем полям в порядке

объявления:

Точка точка = Точка(3, 4);
вывести(точка.сумма_координат());   // выведет 7

Структуры — всегда объекты в куче (передаются по ссылке), с автоматическим подсчётом ссылок — см. ARC.

Слабые ссылки

Поле, объявленное как слабая Тип, не увеличивает счётчик ссылок — нужно для разрыва циклических ссылок (например, родитель ↔ потомок):

структура Цель
    текст имя;
конец

структура Держатель
    текст имя;
    слабая Цель цель;    // не увеличивает счётчик ссылок "Цель"
конец

функция главная(): целое
    Цель цель = Цель("моя цель");
    Держатель держатель = Держатель("держатель", цель);
    вывести(держатель.цель.имя);
    вернуть 0;
конец

Проверка живости — .жива()

Перед обращением к цели через слабую ссылку можно (и нужно) проверить, не была ли она уже освобождена — метод жива() доступен на любом доступе к полю, объявленному как слабая:

если (держатель.цель.жива())
    вывести(держатель.цель.имя);
иначе
    вывести("цель уже освобождена");
конец

Работает безопасно даже после того, как цель "логически" умерла (её счётчик сильных ссылок дошёл до нуля) — пока жива хотя бы одна слабая ссылка на неё, компилятор откладывает реальное освобождение памяти именно для того, чтобы жива() могла её безопасно проверить, не рискуя обращением к уже переиспользованной памяти. Как только последняя слабая ссылка тоже перестаёт существовать — отложенное освобождение происходит немедленно.