Vatsal
Vatsal

Reputation: 18181

Where is my variable being stored? (Swift)

One of my little experiments with Swift:

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

x is a value type.

My questions are:

Upvotes: 10

Views: 2282

Answers (1)

Antonio
Antonio

Reputation: 72760

Parameters are passed to functions and methods by value - that means that a copy of the parameter is created and used in the function body.

Parameters received by functions and methods are immutable, which means their value cannot be changed. However the var modifier makes a parameter mutable - what's important to keep into account is that the copy of the parameter is mutable: the parameter passed to the function has no relationship with the parameter received by the function body, besides the initial copy. That said, making a parameter mutable via the var modifier makes it changeable, but its lifetime ends with the function body and does not affect the original parameter passed to the function.

There's another option, the inout modifier, which works like the var, but when the function returns the value is copied back into the variable passed in.

It's worth mentioning that so far I have implicitly taken value types only into account. If an instance of a reference type (class or closure) is passed to the function, as a var parameter, any change made through that parameter is actually done to the instance passed to the function (that's the most significant difference between value and reference types). The instance pointed by the x variable has the same lifetime of the parameter passed to the function.

All that said, in your case it works in a slightly different way. You are returning a closure (ok, they are 2, but that doesn't change the conclusion), and the closure captures x, which causes x to be kept alive for as long as the variable the closure is assigned to is in scope:

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

In the above code, when getter and setter will be deallocated, x (as the variable defined in the store function) will cease to exist too.

To answer to your questions:

  1. x is a variable created when the store function is invoked. Since you are explicitly mentioning value types, then x should be allocated on the stack (as opposed to the heap, which should be used for reference types)
  2. the pitfall is that it's deallocated when the 2 return values (which are reference types, being closure reference types) are deallocated
  3. it could be useful in some niche cases, but generally I would stay away from it - note that it's my own opinion
  4. already described above (when the function returns values are deallocated)

Upvotes: 15

Related Questions