Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • Where exactly is x being stored (in terms of stack/heap)?
  • What are the pitfalls of storing x like this?
  • Is this safe?
  • When is x going to be destroyed (if ever)?
like image 708
Vatsal Manot Avatar asked Aug 13 '15 11:08

Vatsal Manot


People also ask

Where does variable get stored?

The static variables are stored in the data segment of the memory. The data segment is a part of the virtual address space of a program. All the static variables that do not have an explicit initialization or are initialized to zero are stored in the uninitialized data segment( also known as the BSS segment).

What is variable in Swift?

1. Swift Variables. In programming, a variable is a container (storage area) to hold data. For example, var num = 10. Here, num is a variable storing the value 10.

How do you store a function in a variable in Swift?

To assign function to a variable in Swift, declare a variable that takes specific set/type of parameters and return a specific type of value. Then we can assign a function that has same type of parameters and return value to this variable.


1 Answers

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)
like image 89
Antonio Avatar answered Oct 03 '22 14:10

Antonio