ความหมายความเท่ากันแบบกำหนดเอง
นำกฎความเท่ากันที่ถูกต้องตามโดเมนมาใช้
ความหมายความเท่ากันแบบกำหนดเอง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
เมื่อค่าเริ่มต้นของ == ไม่ถูกต้อง
== ที่สังเคราะห์ขึ้นจะเปรียบเทียบคุณสมบัติที่จัดเก็บไว้ทุกรายการ บางครั้งเงื่อนไขนี้เข้มงวดเกินไป (คุณสนใจเฉพาะรหัสประจำตัว) หรือไม่เข้มงวดพอ ในกรณีนี้คุณต้องเขียน == เอง
ความเท่ากันตามเอกลักษณ์
ถือว่าระเบียนสองรายการเท่ากันเมื่อรหัสประจำตัวตรงกัน โดยไม่สนใจฟิลด์อื่น:
struct Account: Equatable {
let id: Int
var balance: Int
static func == (l: Account, r: Account) -> Bool { l.id == r.id }
}
print(Account(id: 1, balance: 10) == Account(id: 1, balance: 999)) // trueความเท่ากันโดยไม่คำนึงถึงตัวพิมพ์เล็กใหญ่
ปรับรูปแบบข้อมูลให้เป็นมาตรฐานก่อนเปรียบเทียบ:
struct Username: Equatable {
let raw: String
static func == (l: Username, r: Username) -> Bool {
l.raw.lowercased() == r.raw.lowercased()
}
}
print(Username(raw: "Ann") == Username(raw: "ANN")) // trueทำให้ Hashable สอดคล้องกัน
หากคุณปรับแต่ง == คุณ MUST ปรับ hash(into:) ให้ใช้ฟิลด์เดียวกันด้วย มิฉะนั้นค่าที่เท่ากันอาจมีฮาชต่างกันและทำให้เซตทำงานผิดพลาด
ทำให้ == และ hash(into:) ตรงกัน
ทั้งสองอย่างใช้เฉพาะ id จึงยังคงสอดคล้องกัน:
struct User: Hashable {
let id: Int
var name: String
static func == (l: User, r: User) -> Bool { l.id == r.id }
func hash(into h: inout Hasher) { h.combine(id) }
}
print(Set([User(id: 1, name: "A"), User(id: 1, name: "B")]).count) // 1ความเท่ากันที่ไม่สนใจแคช
ไม่นำฟิลด์ที่คำนวณหรือแคชไว้มาใช้ในการเปรียบเทียบ:
struct Doc: Equatable {
let text: String
var cachedWordCount: Int
static func == (l: Doc, r: Doc) -> Bool { l.text == r.text }
}
let a = Doc(text: "hi", cachedWordCount: 1)
let b = Doc(text: "hi", cachedWordCount: 999)
print(a == b) // trueความเท่ากันของจำนวนทศนิยมแบบยืดหยุ่น
เปรียบเทียบค่า double ภายในระยะเอปไซลอน แทนการเปรียบเทียบให้ตรงกันทุกหลัก:
struct Measure: Equatable {
let value: Double
static func == (l: Measure, r: Measure) -> Bool {
abs(l.value - r.value) < 0.0001
}
}
print(Measure(value: 0.1 + 0.2) == Measure(value: 0.3)) // trueความเท่ากันจากบางฟิลด์
เปรียบเทียบเฉพาะส่วนที่มีความหมายสำหรับความเท่ากันในโดเมน:
struct Card: Equatable {
let rank: Int
let suit: String
let isFaceUp: Bool // display state, not identity
static func == (l: Card, r: Card) -> Bool {
l.rank == r.rank && l.suit == r.suit
}
}
print(Card(rank: 1, suit: "H", isFaceUp: true) == Card(rank: 1, suit: "H", isFaceUp: false)) // trueปฏิบัติตามกฎของ Equatable
== แบบกำหนดเองต้องยังคงมีสมบัติสะท้อนกลับ (a == a), สมมาตร (a == b หมายความว่า b == a) และถ่ายทอดได้ การละเมิดกฎเหล่านี้จะทำให้คอลเลกชันและอัลกอริทึมสับสน
การนำไปใช้งานแบบสมมาตร
การเปรียบเทียบรูปแบบที่ปรับเป็นมาตรฐานแล้วช่วยคงสมบัติสมมาตรไว้:
struct Email: Equatable {
let address: String
static func == (l: Email, r: Email) -> Bool {
l.address.lowercased() == r.address.lowercased()
}
}
let x = Email(address: "A@x.com")
let y = Email(address: "a@X.com")
print(x == y, y == x) // true trueความเท่ากันแบบกำหนดเองในเซต
เนื่องจากการตรวจสอบความเท่ากันและการทำฮาชโดยใช้เฉพาะรหัสประจำตัวสอดคล้องกัน เซตจึงถือว่าค่าที่มีรหัสประจำตัวเดียวกันเป็นค่าเดียว:
struct Item: Hashable {
let id: Int
var note: String
static func == (l: Item, r: Item) -> Bool { l.id == r.id }
func hash(into h: inout Hasher) { h.combine(id) }
}
let s: Set<Item> = [Item(id: 1, note: "x"), Item(id: 1, note: "y")]
print(s.count) // 1ตรวจสอบความเข้าใจอย่างรวดเร็ว
หลังจากเขียน == แบบกำหนดเองที่ใช้เพียงบางฟิลด์แล้ว คุณต้องทำอะไรอีก?
สรุป
คุณได้เรียนรู้เกี่ยวกับความเท่ากันแบบกำหนดเอง:
- เขียน
==เองเมื่อการเปรียบเทียบโครงสร้างทั้งหมดตามค่าเริ่มต้นไม่ถูกต้อง - กรณีที่พบบ่อย ได้แก่ ใช้เฉพาะรหัสประจำตัว, ไม่คำนึงถึงตัวพิมพ์เล็กใหญ่, ใช้เอปไซลอนกับจำนวนทศนิยม และไม่รวมแคช
- ทำให้
hash(into:)สอดคล้องกับฟิลด์ชุดเดียวกัน - รักษาสมบัติสะท้อนกลับ สมมาตร และถ่ายทอดได้
เรียนจบหลักสูตรแล้ว! ถัดไป: CustomStringConvertible และ Mirror
คำถามที่พบบ่อย
บทเรียน “ความหมายความเท่ากันแบบกำหนดเอง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ความหมายความเท่ากันแบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ความหมายความเท่ากันแบบกำหนดเอง”
นำกฎความเท่ากันที่ถูกต้องตามโดเมนมาใช้ คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ความหมายความเท่ากันแบบกำหนดเอง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Equatable ที่สังเคราะห์อัตโนมัติ
- Hashable และ hash(into:)
- Comparable และการเรียงลำดับ
- ความหมายความเท่ากันแบบกำหนดเอง