为了理解结构体和类之间的区别,我们需要知道值类型和引用类型之间的主要区别。结构是值类型,这意味着对它们的每次更改都只会修改该值,类是引用类型,并且引用类型的每次更改都会修改在该内存或引用位置分配的值。例如:
让我们从一个类开始,这个类符合 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
好吧,这里发生了什么,为什么如果我们只是改变了 pointsClassInstanceB 的 x 值,它也改变了 pointClassInstanceA 的 x 值?好吧,这显示了引用类型是如何工作的,当我们将实例 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
我们的结构与我们的类基本相同,但是现在您可以看到,当您打印 pointStructInstanceA 的 x 值时,这种情况并没有改变,这是因为值类型的工作方式不同,并且它们的一个实例上的每次更改将是“独立的”,不会影响对方。
Swift 建议使用更多的值类型,你可以看出他们的库是基于结构的,以避免引用类型带来的问题,比如无意中修改值等。结构是 Swift 的方式。
希望对您有所帮助。