كيفية إضافة الأصفار بشكل صحيح للأرقام في Go: دليل التنسيق

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

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

ابدأ الدورة

المشكلة الأبدية: "0" على اليسار أم "إزاحة لليمين"؟

\n\n

هل تساءلت يومًا لماذا تبدو أرقام الطلبات في استعلامات SQL مثل 00042، وفي السجلات مثل 23:05:07؟ الأمر بسيط: الأرقام المزودة بأصفار تتم محاذاتها حسب العرض ولا تفسد الترتيب. لكن في Go، على عكس Python أو JavaScript، لا توجد طريقة مدمجة zfill. وهنا تبدأ المتعة.

\n\n

على Stack Overflow، حصد سؤال "How to pad a number with zeros when printing?" آلاف المشاهدات وعشرات الإجابات. يبحث الأشخاص ليس فقط عن حل، بل عن حل سريع. في هذه المقالة، سنستعرض جميع الطرق لإضافة أصفار إلى رقم في Go، ونقارن أداءها، ونختار الأفضل لمشروعك.

\n\n

لماذا هذا مهم لمطور Go؟

\n\n

Go هي لغة للبرمجة النظامية، حيث كل نانوثانية لها حسابها. إذا كنت تكتب خدمة عالية التحميل، فإن التنسيق غير الصحيح للسلاسل قد يصبح عنق الزجاجة. خاصة إذا كنت تقوم بتنسيق آلاف الأرقام في الثانية.

\n\n
    \n
  • تسجيل الأحداث (Logging): الطوابع الزمنية، معرفات الطلبات، رموز الأخطاء.
  • \n
  • إنشاء التقارير: CSV، JSON، جداول.
  • \n
  • بروتوكولات الشبكة: طول ثابت للحقول.
  • \n
  • الألعاب والرسومات: محاذاة النص في وحدة التحكم.
  • \n
\n\n

تجاهل الأداء قد يؤدي إلى أن خدمتك تهدر 10% من الوقت في تنسيق الأرقام. لا تصدق؟ دعنا نتحقق.

\n\n

الطريقة رقم 1: الكلاسيكية عبر fmt.Sprintf

\n\n

الطريقة الأكثر وضوحًا والتي يُنصح بها غالبًا هي استخدام fmt.Sprintf مع محدد التنسيق %0Xd، حيث X هو العرض الإجمالي للرقم مع الأصفار.

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    num := 42\n    padded := fmt.Sprintf("%05d", num)\n    fmt.Println(padded) // الإخراج: 00042\n}\n
\n\n

هنا %05d يعني: "أخرج الرقم كعدد صحيح عشري، واملأه من اليسار بالأصفار حتى عرض 5 أحرف". إذا كان الرقم أطول بالفعل (مثل 123456)، فلن تتم إضافة الأصفار - يتم تجاهل العرض.

\n\n

الإيجابيات:

\n
    \n
  • بسيط وسهل القراءة.
  • \n
  • يدعم الأرقام السالبة (ستكون الإشارة على يسار الأصفار).
  • \n
  • يعمل مع أنواع مختلفة: %05d لـ int، %05.2f لـ float.
  • \n
\n\n

السلبيات:

\n
    \n
  • يستخدم الانعكاس (Reflection) داخل fmt - بطيء.
  • \n
  • ينشئ سلسلة و interface{} غير ضروريين.
  • \n
  • غير مناسب للمسارات الحرجة (Hot paths).
  • \n
\n\n

الطريقة رقم 2: strconv.FormatInt السريع مع الإضافة اليدوية

\n\n

إذا كان الأداء حرجًا، استخدم حزمة strconv. إنها تعمل مباشرة مع البايتات، بدون انعكاس.

\n\n
package main\n\nimport (\n    "fmt"\n    "strconv"\n    "strings"\n)\n\nfunc padNumber(num int64, width int) string {\n    s := strconv.FormatInt(num, 10)\n    if len(s) >= width {\n        return s\n    }\n    return strings.Repeat("0", width-len(s)) + s\n}\n\nfunc main() {\n    fmt.Println(padNumber(42, 5)) // 00042\n}\n
\n\n

الإيجابيات:

\n
    \n
  • أسرع بمقدار 2-3 مرات من fmt.Sprintf.
  • \n
  • لا يوجد انعكاس.
  • \n
  • تحكم كامل في المنطق.
  • \n
\n\n

السلبيات:

\n
    \n
  • كود أكثر.
  • \n
  • يحتاج إلى معالجة الأرقام السالبة بشكل منفصل (الإشارة على يسار الأصفار).
  • \n
  • strings.Repeat ينشئ سلسلة جديدة - يمكن تحسينها أكثر.
  • \n
\n\n

الطريقة رقم 3: أقصى أداء عبر strings.Builder

\n\n

لأولئك الذين يريدون استخراج أقصى أداء، هناك طريقة بدون تخصيصات غير ضرورية - استخدام strings.Builder وتخصيص المخزن المؤقت مسبقًا.

\n\n
package main\n\nimport (\n    "fmt"\n    "strconv"\n    "strings"\n)\n\nfunc padNumberFast(num int64, width int) string {\n    s := strconv.FormatInt(num, 10)\n    if len(s)                

المدونات

توصيات الكتب