0Pricing
Swift Academy · บทเรียน

ความหมายความเท่ากันแบบกำหนดเอง

นำกฎความเท่ากันที่ถูกต้องตามโดเมนมาใช้

ความหมายความเท่ากันแบบกำหนดเอง เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. Equatable ที่สังเคราะห์อัตโนมัติ
  2. Hashable และ hash(into:)
  3. Comparable และการเรียงลำดับ
  4. ความหมายความเท่ากันแบบกำหนดเอง
← กลับไปที่ Swift Academy