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

Hashable และ hash(into:)

เปิดให้ใช้เป็นคีย์พจนานุกรมและสมาชิกของเซต

Hashable และ hash(into:) เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

Hashable คืออะไร

Hashable ต่อยอดจาก Equatable และมีค่าฮาชให้ใช้ ชนิดข้อมูลต้องเป็นโปรโตคอลนี้จึงจะใช้เป็นสมาชิกของ Set หรือคีย์ของ Dictionary ได้

Hashable โดยอัตโนมัติ

เช่นเดียวกับ Equatable โครงสร้างและอีนัมที่มีสมาชิกเป็น Hashable จะได้รับการสังเคราะห์ความสามารถนี้:

struct Point: Hashable {
    let x: Int
    let y: Int
}
let set: Set<Point> = [Point(x: 0, y: 0), Point(x: 0, y: 0)]
print(set.count)  // 1  -- duplicate collapsed

การใช้ชนิดข้อมูลเป็นคีย์ของพจนานุกรม

ชนิดข้อมูลที่เป็น Hashable สามารถใช้เป็นคีย์ของพจนานุกรมได้:

struct Coord: Hashable { let r: Int; let c: Int }
var grid: [Coord: String] = [:]
grid[Coord(r: 0, c: 0)] = "start"
print(grid[Coord(r: 0, c: 0)]!)  // "start"

ข้อกำหนดของ Hashable

ค่าที่เท่ากันสองค่า (==) MUST ให้ค่าฮาชเดียวกัน หากคุณปรับแต่งอย่างใดอย่างหนึ่ง ต้องทำให้ทั้งสองอย่างสอดคล้องกัน มิฉะนั้นเซตและพจนานุกรมอาจทำงานผิดพลาด

กำหนด hash(into:) เอง

นำ hash(into:) ไปใช้งานโดยป้อนคุณสมบัติที่เกี่ยวข้องเข้าไปในตัวสร้างฮาช:

struct User: Hashable {
    let id: Int
    let name: String
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    static func == (l: User, r: User) -> Bool { l.id == r.id }
}
print(Set([User(id: 1, name: "A"), User(id: 1, name: "B")]).count)  // 1

การรวมหลายฟิลด์

ป้อนทุกฟิลด์ที่มีส่วนร่วมในการตรวจสอบความเท่ากัน:

struct Pair: Hashable {
    let a: Int
    let b: String
    func hash(into hasher: inout Hasher) {
        hasher.combine(a)
        hasher.combine(b)
    }
}
print(Pair(a: 1, b: "x").hashValue == Pair(a: 1, b: "x").hashValue)  // true

เหตุผลที่ใช้เฉพาะฟิลด์เอกลักษณ์

ทำฮาชเฉพาะฟิลด์ที่ใช้ใน == เท่านั้น การรวมฟิลด์ที่เปลี่ยนแปลงได้เพิ่มเติมอาจทำลายกฎที่ว่าค่าที่เท่ากันต้องมีฮาชเดียวกัน:

struct Doc: Hashable {
    let id: Int       // identity
    var title: String // not part of equality
    func hash(into hasher: inout Hasher) { hasher.combine(id) }
    static func == (l: Doc, r: Doc) -> Bool { l.id == r.id }
}
print(Doc(id: 1, title: "v1") == Doc(id: 1, title: "v2"))  // true

อีนัมแบบ Hashable

อีนัมจะเป็น Hashable โดยอัตโนมัติ (รวมถึงอีนัมที่มีค่าที่แนบมา หากค่าเหล่านั้นเป็น Hashable):

enum Direction: Hashable { case north, south, east, west }
let visited: Set<Direction> = [.north, .north, .east]
print(visited.count)  // 2

การลบค่าซ้ำด้วยเซต

การใช้งานทั่วไปอย่างหนึ่งคือ ลบค่าซ้ำโดยนำค่าทั้งหมดผ่านเซต:

let nums = [1, 2, 2, 3, 3, 3]
let unique = Array(Set(nums)).sorted()
print(unique)  // [1, 2, 3]

ตัวสร้างฮาชสุ่มค่าในแต่ละครั้งที่เรียกใช้โปรแกรม

ค่าฮาชจะได้รับค่าเริ่มต้นที่แตกต่างกันในแต่ละครั้งที่โปรแกรมทำงาน ดังนั้นอย่าบันทึก hashValue ลงดิสก์ และอย่าพึ่งพาตัวเลขที่แน่นอนของมันระหว่างการเปิดโปรแกรมแต่ละครั้ง:

struct K: Hashable { let v: Int }
let h1 = K(v: 5).hashValue
// h1 is stable within this run only
print(K(v: 5) == K(v: 5))  // true  -- equality is what to rely on

การนับด้วยพจนานุกรม

คีย์ที่เป็น Hashable ช่วยสร้างการนับความถี่ ซึ่งเป็นรูปแบบที่ใช้กันบ่อยมาก:

let letters = ["a", "b", "a", "c", "b", "a"]
var counts: [String: Int] = [:]
for l in letters { counts[l, default: 0] += 1 }
print(counts["a"]!)  // 3

ตรวจสอบความเข้าใจอย่างรวดเร็ว

hash(into:) ต้องปฏิบัติตามกฎใดเมื่อเทียบกับ ==?

สรุป

คุณได้เรียนรู้เกี่ยวกับ Hashable:

  • Hashable ต่อยอดจาก Equatable และจำเป็นสำหรับคีย์ของ Set/Dictionary
  • โครงสร้างและอีนัมที่มีสมาชิกเป็น Hashable จะได้รับการสังเคราะห์โดยอัตโนมัติ
  • กำหนด hash(into:) เอง โดยรวมเฉพาะฟิลด์เอกลักษณ์ที่ใช้ใน ==
  • ค่าที่เท่ากันต้องมีฮาชเท่ากัน และค่าฮาชจะถูกสุ่มใหม่ในแต่ละครั้งที่เรียกใช้โปรแกรม

ถัดไป: Comparable และการเรียงลำดับ

คำถามที่พบบ่อย

บทเรียน “Hashable และ hash(into:)” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “Hashable และ hash(into:)” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “Hashable และ hash(into:)”

เปิดให้ใช้เป็นคีย์พจนานุกรมและสมาชิกของเซต คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “Hashable และ hash(into:)” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม

ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

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