เพื่อที่จะเข้าใจความแตกต่างระหว่างโครงสร้างและคลาสเราจำเป็นต้องทราบความแตกต่างที่สำคัญระหว่างค่าและประเภทอ้างอิง Structs เป็นประเภทค่าและนั่นหมายความว่าการเปลี่ยนแปลงทุกอย่างจะเปลี่ยนค่านั้น Classes เป็นประเภทการอ้างอิงและการเปลี่ยนแปลงในประเภทการอ้างอิงทุกครั้งจะปรับเปลี่ยนค่าที่จัดสรรในหน่วยความจำหรือการอ้างอิงนั้น ตัวอย่างเช่น:
เรามาเริ่มด้วยคลาสคลาสนี้สอดคล้องกับ 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 ของ pointsClassInstanceB มันก็เปลี่ยนค่า 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 ของ pointStructInstance ในกรณีนี้มันไม่เปลี่ยนแปลงและนี่เป็นเพราะประเภทของค่าทำงานแตกต่างกันและการเปลี่ยนแปลงทุกอย่างในอินสแตนซ์ของพวกเขาจะเป็น " อิสระ "และจะไม่ส่งผลกระทบอื่น ๆ
Swift แนะนำให้ใช้ประเภทของค่ามากขึ้นและคุณสามารถบอกได้ว่าไลบรารีของพวกเขานั้นขึ้นอยู่กับโครงสร้างเพื่อหลีกเลี่ยงปัญหาที่ชนิดของการอ้างอิงนำมาเช่นการปรับเปลี่ยนค่าโดยไม่ตั้งใจเป็นต้นโครงสร้างเป็นวิธีที่จะดำเนินการต่อไปอย่างรวดเร็ว หวังว่ามันจะช่วย