Где хранятся структуры в Swift: на стеке или куче
Что проверяют
Дадите ли вы точный ответ вместо заученного правила, и знаете ли, как проверить это на практике, а не на словах.
Как отвечать
Правильная формулировка: структура хранится там, где хранится её владелец, а не «всегда на стеке».
Локальная переменная функции обычно живёт на стеке. Но та же структура окажется в куче, если она поле класса, если её захватило убегающее замыкание, если она упакована в протокольный тип и не помещается в трёхсловный встроенный буфер, если лежит в косвенном перечислении или в коллекции.
Отдельно стоит сказать про коллекции: Array, String, Dictionary сами структуры, но их содержимое всегда в куче, а копирование при записи откладывает реальное копирование буфера до первой мутации при нескольких владельцах.
Самое ценное в ответе это как проверить, а не как считается. Способы такие:
- флаг компилятора для отчёта об оптимизации размещения (
-Xllvm -sil-print-debuginfoи родственные опции), где видно, ушло ли значение в кучу; - инструменты профилирования: Allocations в Instruments показывает фактические выделения;
- простой признак в коде: если значение не покидает функцию и его адрес никуда не передаётся, компилятор почти наверняка оставит его на стеке.
Практический вывод: выбирать структуру или класс нужно по смыслу (нужна независимая копия или общая ссылка), а вопросы размещения решать замером, когда действительно упёрлись в производительность.
Где спотыкаются
Отвечают одним предложением про стек и не могут объяснить случай со свойством класса.
Считают, что большой массив структур целиком лежит на стеке.
Оптимизируют размещение вслепую, без профилирования, и меняют семантику типа ради выигрыша, которого не измеряли.