Структуры
структура Точка
целое х;
целое у;
функция сумма_координат(): целое
вернуть это.х + это.у;
конец
конец
- Поля объявляются как обычные переменные, без значений по умолчанию
- Методы — обычные функции внутри тела структуры
это— ссылка на текущий экземпляр внутри метода (аналог
self/this в других языках)
- Конструктор генерируется автоматически, по всем полям в порядке
объявления:
Точка точка = Точка(3, 4);
вывести(точка.сумма_координат()); // выведет 7
Структуры — всегда объекты в куче (передаются по ссылке), с автоматическим подсчётом ссылок — см. ARC.
Слабые ссылки
Поле, объявленное как слабая Тип, не увеличивает счётчик ссылок —
нужно для разрыва циклических ссылок (например, родитель ↔ потомок):
структура Цель
текст имя;
конец
структура Держатель
текст имя;
слабая Цель цель; // не увеличивает счётчик ссылок "Цель"
конец
функция главная(): целое
Цель цель = Цель("моя цель");
Держатель держатель = Держатель("держатель", цель);
вывести(держатель.цель.имя);
вернуть 0;
конец
Проверка живости — .жива()
Перед обращением к цели через слабую ссылку можно (и нужно) проверить,
не была ли она уже освобождена — метод жива() доступен на любом
доступе к полю, объявленному как слабая:
если (держатель.цель.жива())
вывести(держатель.цель.имя);
иначе
вывести("цель уже освобождена");
конец
Работает безопасно даже после того, как цель "логически" умерла (её
счётчик сильных ссылок дошёл до нуля) — пока жива хотя бы одна слабая
ссылка на неё, компилятор откладывает реальное освобождение памяти
именно для того, чтобы жива() могла её безопасно проверить, не
рискуя обращением к уже переиспользованной памяти. Как только
последняя слабая ссылка тоже перестаёт существовать — отложенное
освобождение происходит немедленно.