Consider this function:
func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
Here I am assigning this function to another variable
var mathFunction: (Int, Int) -> Int = addTwoInts
Here addTwoInts
is a value type or reference type? And why?
Closures and functions are Reference types. This is stated in the Swift language documentation: Closures
I would say that a function type fits best with the definition of a reference type:
Reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used.
However I don't think this is a particularly useful distinction to make, IMO it would also be valid to make the argument that functions are value types (as technically speaking they consist of a pointer and a reference, both of which are copied when the function value is passed about).
The more useful distinction to make is that functions have reference semantics, meaning that it's possible to observe some kind of shared state between instances. This is not the same as being a reference type – it's possible for value types to have reference semantics, and for reference types to have value semantics.
For example here's a value type with reference semantics:
var foo = 0
struct S {
var bar: Int {
get { return foo }
nonmutating set { foo = newValue }
}
}
let s = S()
let s1 = s
s.bar += 1
print(s.bar) // 1
print(s1.bar) // 1
Both s
and s1
share global state, and this is observable by mutating it.
And here's a reference type with value semantics:
final class C {
let foo = 0
}
let c = C()
let c1 = c
print(c.foo) // 0
print(c1.foo) // 0
Although both c
and c1
share state, this isn't directly observable because that shared state is immutable.
So, why do functions have reference semantics? Because they can contain captured variables, which is shared mutable state that can be observed.
For example:
func makeFn() -> () -> Int {
var foo = 0
return {
foo += 1
return foo
}
}
let fn = makeFn()
let fn1 = fn
print(fn()) // 1
print(fn1()) // 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With