الأقواس المتعرجة في Rust: كيفية إظهار { و } في format! بدون أخطاء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا لا تحب Rust الأقواس المتعرجة؟

\n\n

إذا كنت قد كتبت في Rust من قبل وحاولت إخراج شيء مثل { "name": "Rust" } عبر println!، فمن المحتمل أنك رأيت هذا:

\n\n
println!("{ "name": "Rust" }"); // خطأ في الترجمة!
\n\n

يخبرك المترجم بسخرية: "invalid reference to argument 'name' — no argument named 'name' found". وتظل في حيرة: كيف يمكن إخراج الأقواس المتعرجة في السلسلة؟ ففي Python يتم ذلك عبر {{ }}، لكن الأمر أبسط هناك. في Rust فلسفتها الخاصة: الأقواس المتعرجة ليست مجرد رموز، بل هي جزء من نظام تنسيق قوي، مستعار من Python، ولكن مع فروق دقيقة.

\n\n

في هذه المقالة، سنشرح جميع طرق إفلات الأقواس المتعرجة في Rust: من الأساسي {{ }} إلى الحيل مع Debug و raw string literals. ستتعلم كيفية إخراج JSON، وتوليد الكود، والعمل مع القوالب دون الوقوع في فخاخ المترجم.

\n\n

لماذا الأقواس المتعرجة مميزة؟

\n\n

في Rust، تستخدم الماكرو format! و println! و write! و format_args! الأقواس المتعرجة كـ علامات استبدال. على سبيل المثال:

\n\n
let name = "Rust";\nprintln!("Hello, {}!", name); // Hello, Rust!
\n\n

هنا {} هو placeholder يتم استبداله بقيمة المتغير. ولكن ماذا لو كنت بحاجة إلى الرمز نفسه { أو }؟ تستخدم Rust خدعة بسيطة: مضاعفة الأقواس.

\n\n

الطريقة 1: المضاعفة التقليدية {{ و }}

\n\n

أبسط وأوضح طريقة هي كتابة قوسين متعرجين متتاليين. الزوج الأول {{ يتحول إلى قوس واحد {، و }} يتحول إلى قوس واحد }.

\n\n

مثال 1: إفلات بسيط

\n
fn main() {\n    let text = format!("الدالة main() {{ ... }}");\n    println!("{}", text);\n    // الإخراج: الدالة main() { ... }\n}
\n\n

مثال 2: إفلات مع استبدال

\n
fn main() {\n    let lang = "Rust";\n    let year = 2015;\n    let result = format!("{{ \\"lang\\": \\"{}\\", \\"year\\": {} }}", lang, year);\n    println!("{}", result);\n    // الإخراج: { "lang": "Rust", "year": 2015 }\n}
\n\n

تعمل هذه الطريقة في كل مكان: في println! و write! و format!. تذكر القاعدة: قوسان = قوس واحد.

\n\n

الطريقة 2: الوسائط المسماة والإفلات

\n\n

إذا كنت تستخدم وسائط مسماة (مثل {name})، فإن الإفلات يعمل أيضًا، ولكن يجب الانتباه إلى موضع الأقواس.

\n\n

مثال 3: العناصر النائبة المسماة والأقواس

\n
fn main() {\n    let user = "Alice";\n    // نريد إخراج: مرحبًا، {Alice}!\n    println!("مرحبًا، {{{}}}!", user);\n    // الإخراج: مرحبًا، {Alice}!\n}
\n\n

تحليل السلسلة "مرحبًا، {{{}}}!":\n

    \n
  • {{ → يخرج {
  • \n
  • {} → يستبدل بـ user
  • \n
  • }} → يخرج }
  • \n
\n

\n\n

هام: عدد الأقواس دائمًا زوجي للإفلات. إذا كان لديك {{{ فهذا خطأ، لأن ثلاثة أقواس لا تشكل زوجًا صحيحًا.

\n\n

الطريقة 3: استخدام تنسيق Debug ({:?})

\n\n

أحيانًا تريد إخراج بنية بيانات بحيث تظهر مع أقواس متعرجة تلقائيًا. على سبيل المثال، عند التصحيح أو توليد JSON.

\n\n

مثال 4: إخراج بنية عبر Debug

\n
#[derive(Debug)]\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let p = Point { x: 10, y: 20 };\n    println!("{:?}", p);\n    // الإخراج: Point { x: 10, y: 20 }\n}
\n\n

يضيف trait Debug الأقواس حول الحقول بنفسه. هذا مناسب إذا كنت بحاجة إلى إظهار حالة الكائن بسرعة. ولكن إذا كنت بحاجة تحديدًا إلى JSON أو شيء آخر

المدونات

توصيات الكتب