2015-08-13 2 views
9

Один из моих маленьких опытов с Swift:Где хранится моя переменная? (Swift)

func store<T>(var x: T) -> (getter: (Void -> T), setter: (T -> Void)) 
{ 
    return ({ x }, { x = $0 }) 
} 

x является типом значения.

Мои вопросы:

  • Где именно x хранится (в виде стека/кучи)?
  • Каковы подводные камни хранения x? (Я прочитал лот аргументов о стеке и куче, и я удивительно хочу услышать о них еще несколько!)
  • Безопасно ли это?
  • Когда будет x будет уничтожено (если когда-либо)?

ответ

14

Параметры передаются функциям и методам по значению - это означает, что копия параметра создается и используется в теле функции.

Параметры, полученные функциями и методами, неизменяемы, что означает, что их значение не может быть изменено. Однако модификатор var делает параметр изменчивым - важно помнить, что параметр параметра изменен: параметр, переданный функции, не имеет отношения к параметру, полученному телом функции, помимо начальной копии. Тем не менее, изменение параметра, изменяемого с помощью модификатора var, делает его изменчивым, но его время жизни заканчивается телом функции и не влияет на исходный параметр, переданный функции.

Там еще один вариант, модификатор inout, который работает как var, но когда функция возвращает значение копируется обратно в переменную передается в.

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

Все, что сказано, в вашем случае это работает несколько иначе. Вы возвращаете закрытие (нормально, они равны 2, но это не меняет вывода), а закрытие фиксирует x, что приводит к тому, что x сохраняется в памяти до тех пор, пока переменная, которую назначается закрытие, находится в области:

let x = 5 
let (getter, setter) = store(x) 

в приведенном выше коде, когда getter и setter будут высвобождены, x (как переменная определяется в функции store) прекратит свое существование тоже.

Чтобы ответить на ваши вопросы:

  1. x переменная создается, когда функция store вызывается.Поскольку вы явно указываете типы значений, тогда x должен быть выделен в стеке (в отличие от кучи, которая должна использоваться для ссылочных типов)
  2. ошибка заключается в том, что она освобождается, когда 2 возвращаемых значения (которые являются ссылочными типами) , являющиеся закрывающими ссылочными типами) освобождаются
  3. Это может быть полезно в некоторых случаях, но в целом я бы держался подальше от него - обратите внимание, что это мое собственное мнение
  4. , уже описанное выше (когда функция возвращает значения освобождены)
+0

Блестяще сформулированный, я очень ценю время, которое вы вложили в это! Тем не менее, я не понимаю оправдания за ловушкой, которую вы описываете. –

+0

Это должно быть проще: если 'T' - тип значения, переменная выделяется в стеке, а замыкания (являющиеся ссылочными типами) в куче. Таким образом, данные хранятся в стеке и сохраняются в двух экземплярах, выделенных в куче. – Antonio

+0

Имейте в виду, что реализация COW стандартного Swift Array, вероятно, хранит его данные в куче, даже если сам массив является значением типа –

Смежные вопросы