Aby zrozumieć różnicę między Strukturami a Klasami, musimy znać główną różnicę między wartościami a typami odniesienia. Struktury są typami wartości, co oznacza, że każda zmiana na nich po prostu zmodyfikuje tę wartość, Klasy są typami referencyjnymi, a każda zmiana w typie referencyjnym zmodyfikuje wartość przydzieloną w tym miejscu pamięci lub referencji. Na przykład:
Zacznijmy od klasy, ta klasa jest zgodna z Equatable tylko po to, aby móc porównywać instancje, tworzymy instancję o nazwie, pointClassInstanceA
a inną o nazwie pointClassInstanceB
przypisujemy klasę A do klasy B, teraz twierdzenie mówi, że są takie same ...
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
Ok, co się tutaj stało, dlaczego po prostu zmieniliśmy wartość x pointClassInstanceB, zmieniła się również wartość x pointClassInstanceA? pokazuje to, jak działają typy referencji, kiedy przypisujemy instancję A, jako wartość instancji B, a następnie modyfikujemy X jednego z nich, zmieni to oba X, ponieważ dzielą to samo odwołanie, a to, co się zmieniło, była wartością tego odniesienie.
Zróbmy to samo, ale ze strukturą
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
Mamy zasadniczo taką samą strukturę jak nasza klasa, ale teraz widać, że po wydrukowaniu wartości x pointStructInstanceA w tym przypadku nie uległa ona zmianie, a to dlatego, że typy wartości działają inaczej i każda zmiana w jednym z ich wystąpień będzie „ niezależne ”i nie wpłynie na innych.
Swift sugeruje użycie większej liczby typów wartości i można powiedzieć, że ich biblioteki są oparte na strukturach, aby uniknąć problemów związanych z typami odwołań, takich jak niezamierzona modyfikacja wartości itp. Struktury są sposobem na przejście do Swift. Mam nadzieję, że to pomoże.