0Pricing
Learn Rust Coding · درس

واجهة Entry والقيم الافتراضية

حدّث القيم بطريقة سهلة وأنيقة

واجهة Entry والقيم الافتراضية درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.

لماذا واجهة Entry؟

غالبًا ما تريدون تحديث قيمة إذا كان المفتاح موجودًا، أو إدراج قيمة افتراضية إذا لم يكن موجودًا.

تنفيذ ذلك باستخدام get مع insert أمر غير مريح. أما واجهة entry فتنفذه بوضوح في خطوة واحدة.

تعيد entry خانة

يمنحكم استدعاء entry(key) مقبضًا إلى موضع ذلك المفتاح في الخريطة.

ومن خلال هذا المقبض تقررون ما يجب فعله: ملء الخانة بقيمة افتراضية أو تعديل القيمة الموجودة فيها.

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, i32> = HashMap::new();
    m.entry("a").or_insert(0);
    println!("{}", m["a"]);
}

or_insert

تُدرج or_insert(default) القيمة الافتراضية فقط إذا كان المفتاح مفقودًا، ثم تعيد مرجعًا قابلًا للتغيير إلى القيمة.

إذا كان المفتاح موجودًا، فسيتم تجاهل القيمة الافتراضية وتحصلون على القيمة الموجودة.

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("a", 10);
    m.entry("a").or_insert(99);
    m.entry("b").or_insert(99);
    println!("a={}, b={}", m["a"], m["b"]);
}

التعديل من خلال المرجع

بما أن or_insert تعيد مرجعًا قابلًا للتغيير، يمكنكم تغيير القيمة فورًا.

أزيلوا الإشارة المرجعية باستخدام * لتحديث القيمة في مكانها. هذه هي الفكرة الأساسية للعد.

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    let count = m.entry("hits").or_insert(0);
    *count += 1;
    *count += 1;
    println!("hits = {}", m["hits"]);
}

العد داخل حلقة

النمط المعتاد هو: الحصول على خانة كل عنصر، وتعيين قيمتها الافتراضية إلى الصفر، ثم زيادتها.

وبذلك تُحصى مرات الظهور، مع سطر منطقي واحد فقط لكل عنصر.

use std::collections::HashMap;

fn main() {
    let mut counts = HashMap::new();
    for c in "hello".chars() {
        *counts.entry(c).or_insert(0) += 1;
    }
    println!("l appears {} times", counts[&'l']);
}

or_insert_with

عندما يكون إنشاء القيمة الافتراضية مكلفًا، استخدموا or_insert_with. فهي تستقبل closure لا يعمل إلا إذا كان المفتاح مفقودًا.

وهذا يتجنب إنشاء قيمة قد لا تحتاجون إليها أبدًا.

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, Vec<i32>> = HashMap::new();
    m.entry("nums").or_insert_with(Vec::new).push(1);
    m.entry("nums").or_insert_with(Vec::new).push(2);
    println!("{:?}", m["nums"]);
}

and_modify

تشغّل and_modify closure على القيمة فقط إذا كان المفتاح موجودًا مسبقًا.

يمكنكم ربطها مع or_insert لمعالجة الحالتين: التعديل عند وجود المفتاح، وإلا إدراج قيمة ابتدائية.

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("x", 5);
    m.entry("x").and_modify(|v| *v += 10).or_insert(0);
    m.entry("y").and_modify(|v| *v += 10).or_insert(1);
    println!("x={}, y={}", m["x"], m["y"]);
}

or_default

إذا كان نوع القيمة يملك Default، مثل 0 للأعداد أو Vec فارغة، تستخدم or_default هذه القيمة.

وهي اختصار لـ or_insert(Default::default()).

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, i32> = HashMap::new();
    *m.entry("score").or_default() += 7;
    println!("score = {}", m["score"]);
}

إنشاء قوائم لكل مفتاح

تتألق واجهة entry عند تجميع العناصر في متجهات.

لكل مفتاح، استخدموا Vec فارغة كقيمة افتراضية في المرة الأولى، ثم أضيفوا العناصر إلى المتجه الموجود.

use std::collections::HashMap;

fn main() {
    let mut groups: HashMap<bool, Vec<i32>> = HashMap::new();
    for n in [1, 2, 3, 4] {
        groups.entry(n % 2 == 0).or_default().push(n);
    }
    println!("evens: {:?}", groups[&true]);
}

لماذا لا نستخدم get + insert؟

يؤدي استخدام get ثم insert بشكل منفصل إلى البحث عن المفتاح مرتين، كما يتعارض مع مدقق الاستعارة.

أما واجهة entry فتنفذ بحثًا واحدًا وتمنحكم مرجعًا آمنًا واحدًا بالضبط، لذا فهي أسرع وأنظف.

جمع الأجزاء معًا

يجتمع العد والقيمة الافتراضية هنا لمعرفة عدد الكلمات المختلفة التي تبدأ بكل حرف.

لاحظوا تطبيق نمط العد ذي السطر الواحد.

use std::collections::HashMap;

fn main() {
    let words = ["ant", "art", "bee"];
    let mut by_first: HashMap<char, i32> = HashMap::new();
    for w in words {
        *by_first.entry(w.chars().next().unwrap()).or_insert(0) += 1;
    }
    println!("a: {}", by_first[&'a']);
}

تحقق سريع

تريدون عد الأحرف مع إجراء بحث واحد لكل حرف.

مراجعة

تتيح لكم واجهة entry الإدراج أو التحديث من خلال بحث واحد.

استخدمتم or_insert وor_insert_with وor_default وand_modify لعد العناصر وإنشاء قوائم لكل مفتاح بوضوح.

الأسئلة الشائعة

هل درس «واجهة Entry والقيم الافتراضية» مجاني؟

نعم — نص درس «واجهة Entry والقيم الافتراضية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.

ماذا ستتعلم في «واجهة Entry والقيم الافتراضية»؟

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

هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟

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

كم من الوقت يستغرق درس «واجهة Entry والقيم الافتراضية»؟

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

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

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

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

  1. إنشاء HashMap
  2. واجهة Entry والقيم الافتراضية
  3. العمل مع HashSet
  4. العدّ والتجميع
← العودة إلى Learn Rust Coding