مقدمة: العامل الثلاثي — صديق أم عدو؟
\n\nإذا أتيت إلى Go من عالم C أو C++ أو Java أو JavaScript، فأنت بالتأكيد معتاد على البنية المختصرة:
\n\nint max = (a > b) ? a : b;\n\nهذا هو العامل الثلاثي. إنه مضغوط وأنيق ويسمح بكتابة فرع بسيط في سطر واحد. ولكن عندما تبدأ في الكتابة بلغة Go، تنتظرك مفاجأة: لا يوجد عامل ثلاثي في Go. إطلاقاً. لا يوجد ? :.
لماذا اتخذ مبتكرو اللغة هذه الخطوة؟ كيف تكتب الآن تعيينات شرطية قصيرة؟ والأهم من ذلك — كيف تفعل ذلك بشكل اصطلاحي، أي بالأسلوب المقبول في مجتمع Go؟
\n\nفي هذه المقالة، سنناقش:
\n- \n
- لماذا لا يوجد عامل ثلاثي في Go (تلميح: هذا قرار متعمد). \n
- كيفية استبدال العامل الثلاثي باستخدام
if-else. \n - تقنيات متقدمة: الدوال، الخرائط (map)، التضمين (inlining). \n
- متى يمكن (ويجب) مخالفة القاعدة. \n
هيا بنا!
\n\nلماذا تخلت Go عن العامل الثلاثي؟
\n\nالإجابة بسيطة وتكمن في فلسفة اللغة: قابلية القراءة أهم من الاختصار.
\n\nروبرت غريزيمر (أحد مبتكري Go) قال ذات مرة: «العامل الثلاثي هو مصدر للأخطاء. من السهل جداً قراءته بشكل خاطئ، خاصة عندما يكون متداخلاً». وهذا صحيح. تذكر على الأقل المثال الشهير من C:
\n\nint x = (a ? b : c) ? d : e;\n\nهل تستطيع فهم ما يفعله بسرعة؟ هذا ما جعل مبتكري Go يقررون أنه من الأفضل التضحية بسطر واحد، ولكن جعل الكود واضحاً.
\n\nفي Go، الأولوية هي وضوح النوايا. إذا كنت تكتب شرطاً، فليكن صريحاً. غالباً ما يتحول العامل الثلاثي إلى «رقم سحري»: تنظر إلى السطر ولا تفهم المنطق فوراً. في Go، لا ينبغي أن يحدث هذا.
\n\nالاستبدال الأساسي: if-else كأسلوب اصطلاحي
\n\nأبسط وأصح طريقة لاستبدال العامل الثلاثي هي استخدام if-else العادي. نعم، هذا يستغرق 3 أسطر بدلاً من سطر واحد، لكنه يُقرأ دون عناء.
مثال: إيجاد القيمة القصوى لعددين.
\n\nفي C:
\nint max = (a > b) ? a : b;\n\nفي Go (بشكل اصطلاحي):
\nvar max int\nif a > b {\n max = a\n} else {\n max = b\n}\n\n«لكن هذا أطول!» — ستقول. نعم. لكن انظر إلى الأمر من زاوية أخرى: بعد شهر، ستفتح الكود وسترى المنطق فوراً. لا أقواس، لا غموض. فقط «إذا كان a أكبر من b، فإن max = a، وإلا max = b».
\n\nعلاوة على ذلك، يعتبر مجتمع Go هذا الأسلوب الصحيح الوحيد للشروط البسيطة. لا تحاول «الغش» ووضع كل شيء في سطر واحد — فهذا يعتبر أسلوباً سيئاً.
\n\nتقنيات متقدمة: عندما ترغب في الاختصار
\n\nأحياناً تكتب كوداً حيث يستغرق if-else 10 أسطر، رغم أنه في جوهره مجرد تعيين بسيط. في مثل هذه الحالات، يمكن تطبيق عدة أنماط تحافظ على الاصطلاحية ولكن تجعل الكود أكثر إحكاماً.
1. دالة مساعدة
\n\nإذا كنت تحتاج غالباً إلى الاختيار بين قيمتين، فاستخرج المنطق في دالة. هذا مناسب بشكل خاص للعمليات ذات السطر الواحد.
\n\nfunc ternary(cond bool, a, b string) string {\n if cond {\n return a\n }\n return b\n}\n\n// الاستخدام:\ngreeting := ternary(isMorning, "صباح الخير", "مساء الخير")\n\nهام: لا تسمي الدالة ternary — فهذا يعتبر أسلوباً سيئاً، لأنك تحاول «تهريب» العامل الثلاثي من الباب الخلفي. من الأفضل إعطاء اسم ذي معنى، مثل ifElse أو choose. لكن إذا كنت تكتب لنفسك — فلم لا؟
2. استخدام الخريطة (map) للاختيار
\n\nإذا كان الشرط يقتصر على الاختيار بين خيارين، يمكن استخدام خريطة بمفاتيح منطقية. هذا يبدو غير معتاد، لكنه أحياناً يُقرأ بشكل أفضل.
\n\nvar result = map[bo