مقدمة: لماذا لا تحب Rust الأقواس المتعرجة؟
\n\nإذا كنت قد كتبت في Rust من قبل وحاولت إخراج شيء مثل { "name": "Rust" } عبر println!، فمن المحتمل أنك رأيت هذا:
println!("{ "name": "Rust" }"); // خطأ في الترجمة!\n\nيخبرك المترجم بسخرية: "invalid reference to argument 'name' — no argument named 'name' found". وتظل في حيرة: كيف يمكن إخراج الأقواس المتعرجة في السلسلة؟ ففي Python يتم ذلك عبر {{ }}، لكن الأمر أبسط هناك. في Rust فلسفتها الخاصة: الأقواس المتعرجة ليست مجرد رموز، بل هي جزء من نظام تنسيق قوي، مستعار من Python، ولكن مع فروق دقيقة.
في هذه المقالة، سنشرح جميع طرق إفلات الأقواس المتعرجة في Rust: من الأساسي {{ }} إلى الحيل مع Debug و raw string literals. ستتعلم كيفية إخراج JSON، وتوليد الكود، والعمل مع القوالب دون الوقوع في فخاخ المترجم.
لماذا الأقواس المتعرجة مميزة؟
\n\nفي Rust، تستخدم الماكرو format! و println! و write! و format_args! الأقواس المتعرجة كـ علامات استبدال. على سبيل المثال:
let name = "Rust";\nprintln!("Hello, {}!", name); // Hello, Rust!\n\nهنا {} هو placeholder يتم استبداله بقيمة المتغير. ولكن ماذا لو كنت بحاجة إلى الرمز نفسه { أو }؟ تستخدم Rust خدعة بسيطة: مضاعفة الأقواس.
الطريقة 1: المضاعفة التقليدية {{ و }}
\n\nأبسط وأوضح طريقة هي كتابة قوسين متعرجين متتاليين. الزوج الأول {{ يتحول إلى قوس واحد {، و }} يتحول إلى قوس واحد }.
مثال 1: إفلات بسيط
\nfn main() {\n let text = format!("الدالة main() {{ ... }}");\n println!("{}", text);\n // الإخراج: الدالة main() { ... }\n}\n\nمثال 2: إفلات مع استبدال
\nfn 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!. تذكر القاعدة: قوسان = قوس واحد.
الطريقة 2: الوسائط المسماة والإفلات
\n\nإذا كنت تستخدم وسائط مسماة (مثل {name})، فإن الإفلات يعمل أيضًا، ولكن يجب الانتباه إلى موضع الأقواس.
مثال 3: العناصر النائبة المسماة والأقواس
\nfn main() {\n let user = "Alice";\n // نريد إخراج: مرحبًا، {Alice}!\n println!("مرحبًا، {{{}}}!", user);\n // الإخراج: مرحبًا، {Alice}!\n}\n\nتحليل السلسلة "مرحبًا، {{{}}}!":\n
- \n
{{→ يخرج{\n {}→ يستبدل بـuser\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 أو شيء آخر