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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- Equatable المُنشأ تلقائيًا
- Hashable و hash(into:)
- Comparable والترتيب
- دلالات المساواة المخصصة