Ответ
В Swift хранение на стеке обеспечивается использованием типов-значений (value types), главным образом структур (struct) и перечислений (enum). При создании экземпляра такой тип размещается в стеке вызовов текущего потока (если не происходит escape в кучу, например, при захвате замыканием).
Пример: структура Point, хранящаяся на стеке.
// 1. Объявляем структуру (тип-значение)
struct Point {
var x: Int
var y: Int
// Метод, работающий с мутабельным self (изменяет копию)
mutating func moveBy(x deltaX: Int, y deltaY: Int) {
x += deltaX
y += deltaY
}
}
// 2. Создаем экземпляр. Локальная переменная `origin` размещается на стеке.
func createPoint() {
var origin = Point(x: 0, y: 0) // Выделение памяти на стеке
print("Initial: ((origin.x), (origin.y))")
// 3. Присваивание создает новую, независимую копию на стеке.
var anotherPoint = origin // Копирование значений (copy-on-write для оптимизации)
anotherPoint.x = 10
print("Origin: ((origin.x), (origin.y))") // (0, 0) - не изменился
print("Another: ((anotherPoint.x), (anotherPoint.y))") // (10, 0)
// 4. Передача в функцию также создает копию (если параметр не `inout`).
func printPoint(_ p: Point) {
print("Printed point: ((p.x), (p.y))")
}
printPoint(origin)
// 5. Изменение через mutating метод.
origin.moveBy(x: 5, y: 3)
print("Moved origin: ((origin.x), (origin.y))") // (5, 3)
}
createPoint()
Ключевые характеристики типов-значений (стековых):
- Копирование по значению: При присваивании или передаче в функцию создается новая, независимая копия данных.
- Отсутствие разделяемого состояния: Изменение одной переменной не влияет на другие.
- Автоматическое управление памятью: Память в стеке освобождается автоматически при выходе из области видимости (функции, скоупа).
- Высокая производительность: Выделение и освобождение памяти в стеке — очень быстрые операции (просто сдвиг указателя стека).
Сравнение с типами-ссылками (куча):
| Аспект | Тип-значение (struct, enum) |
Тип-ссылка (class) |
|---|---|---|
| Хранение | Стек (по умолчанию) | Куча (динамическая память) |
| Копирование | Создается новая копия | Копируется указатель (ссылка) |
| Управление памятью | Автоматическое (стек) | ARC (счетчик ссылок) |
| Наследование | Нет (но есть протоколы) | Есть (одиночное) |
| Идентичность | Сравнение по значению (==) |
Сравнение по ссылке (===) |
Важно: Компилятор Swift может применять оптимизации (например, copy-on-write для больших структур), чтобы избежать дорогостоящего копирования, пока данные не будут изменены, но семантика поведения остается value-type.