Я бы сказал, что тип функции лучше всего подходит с определением ссылочного типа :
Ссылочные типы не копируются, когда они назначены переменной или константе,или когда они передаются в функцию.Вместо копии используется ссылка на тот же существующий экземпляр.
Однако я не думаю, что это особенно полезное различие, IMO также было бы правильным сделать аргумент, которыйфункции являются типами значений (так как с технической точки зрения они состоят из указателя и ссылки , которые копируются при передаче значения функции).
Более полезное различие заключается вчто функции имеют эталонную семантику , что означает, что можно наблюдать некое общее состояние между экземплярами.Это не то же самое, что ссылочный тип - для типов значений возможно иметь ссылочную семантику и для ссылочных типов иметь семантику значения.
Например, вот тип значения со ссылочной семантикой:
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
И s
, и s1
совместно используют глобальное состояние, и это можно наблюдать, изменяя его.
А вот ссылочный тип с семантикой значения:
final class C {
let foo = 0
}
let c = C()
let c1 = c
print(c.foo) // 0
print(c1.foo) // 0
Хотяc
и c1
совместно используют состояние, это непосредственно не наблюдается, потому что это совместно используемое состояние является неизменным.
Итак, почему функции имеют ссылочную семантику?Поскольку они могут содержать захваченные переменные, то есть общее изменяемое состояние, которое можно наблюдать.
Например:
func makeFn() -> () -> Int {
var foo = 0
return {
foo += 1
return foo
}
}
let fn = makeFn()
let fn1 = fn
print(fn()) // 1
print(fn1()) // 2