Для того, щоб зрозуміти різницю між структурами та класами, нам потрібно знати головну різницю між значеннями та типовими типами. Структури - це типи значень, і це означає, що кожна зміна на них просто модифікує це значення, Класи - це еталонні типи, і кожна зміна типу посилання змінює значення, виділене в цьому місці пам'яті або посилання. Наприклад:
Почнемо з класу, цей клас відповідає Equatable лише для того, щоб можна було порівнювати екземпляри, ми створюємо екземпляр, який називається pointClassInstanceA
та іншим, що називається, pointClassInstanceB
ми присвоюємо клас A класу B, тепер твердження говорить, що вони однакові ...
class PointClass: Equatable {
var x: Double
var y: Double
init(x: Double, y: Double) {
self.x = x
self.y = y
}
static func == (lhs: PointClass, rhs: PointClass) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
var pointClassInstanceA = PointClass(x: 0, y: 0)
var pointClassInstanceB = pointClassInstanceA
assert(pointClassInstanceA==pointClassInstanceB)
pointClassInstanceB.x = 10
print(pointClassInstanceA.x)
//this prints 10
Добре, що тут сталося, чому, якщо ми просто змінили значення x пунктівClassInstanceB, воно також змінило значення x pointClassInstanceA? добре, це показує, як працюють типи посилань, коли ми присвоюємо екземпляр A як значення екземпляра B, а потім ми модифікуємо X одного з них, він змінить обидва X, оскільки вони мають однакові посилання, а те, що змінилося - це значення довідник.
Зробимо те саме, але зі структурою
struct PointStruct: Equatable {
var x: Double
var y: Double
init(x: Double, y: Double) {
self.x = x
self.y = y
}
static func == (lhs: PointStruct, rhs: PointStruct) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
var pointStructInstanceA = PointStruct(x: 0, y: 0)
var pointStructInstanceB = pointStructInstanceA
assert(pointStructInstanceA==pointStructInstanceB)
pointStructInstanceB.x = 100
print(pointStructInstanceA.x)
//this will print 0
У нас в основному така ж структура, як і у нашого класу, але тепер ви бачите, що при друкуванні значення x pointStructInstanceA цей випадок не змінюється, і це тому, що типи значень працюють по-різному, і кожна зміна в одному з їх екземплярів буде " незалежний »і не вплине на іншого.
Swift пропонує використовувати більше типів значень, і ви можете сказати, що їх бібліотеки базуються на структурах, щоб уникнути проблем, які викликають типи посилань, як ненавмисне зміна значення тощо. Структури - це спосіб продовжити Swift. Сподіваюся, це допомагає.