Keep in mind that the concept of reference semantics is different from the concept of reference types:
A value type can have reference semantics. For example, a file descriptor on Unix platforms is a CInt, but that definitely has reference semantics.
A reference type can have value semantics. The most common example of this is an immutable class.
You can’t use the type system to check for reference semantics.
The question of how to formalise value and reference semantics is super subtle and has been discussed many times here on DevForums, to the point where folks have published research papers on the topic.
On copy, you get a new reference to the same underlying closure (with the same captured state). It's easy to see this by seeing what happens when you mutate the state:
func createCounter(initial: Int) -> () -> Int {
var counter = initial
return {
counter += 1
print("the new counter value is \(counter)")
return counter
}
}
let a = createCounter(initial: 0)
let b = a // new reference the same underlying counter
_ = a() // increment through the reference "a"
_ = b() // increment the same closure through reference "b"
Although I know closure is a reference type (I remember this is mentioned in the swift language book), I don't think this example is sufficient to prove it. It only proves that the captured variable (counter) has reference semantic. If closure was a value type, it would have the same output
@King-Eternal I think you'll find the Modern Swift API Design talk from WWDC 2019 quite interesting and informative on the subject of reference vs value semantics (and details how a value type that contains a reference value can take on reference semantics)
My take on value vs reference topic, is that every type is a value type, but it varies per type what is included and what is excluded from the definition of value. In case of references to the mutable class, only object identity is part of the value.