0Pricing
Swift Academy · درس

‏Hashable و hash(into:)

مكّن استخدام النوع كمفاتيح للقواميس وأعضاء للمجموعات.

‏Hashable و hash(into:) درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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

استخدام نوع كمفتاح في Dictionary

يمكن للأنواع من نوع 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

يجب أن تنتج القيمتان المتساويتان (==) قيمة التجزئة نفسها. وإذا خصصتم أحدهما، فاحرصوا على اتساقهما، وإلا فلن تعمل المجموعات والقواميس كما ينبغي.

تخصيص 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

إزالة التكرارات باستخدام Set

من الاستخدامات الشائعة: إزالة التكرارات عبر المرور على Set:

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

العد باستخدام Dictionary

تتيح مفاتيح 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:)» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «‏Hashable و hash(into:)»؟

مكّن استخدام النوع كمفاتيح للقواميس وأعضاء للمجموعات. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «‏Hashable و hash(into:)»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. ‏Equatable المُنشأ تلقائيًا
  2. ‏Hashable و hash(into:)
  3. ‏Comparable والترتيب
  4. دلالات المساواة المخصصة
← العودة إلى Swift Academy