الانتقال إلى المحتوى الرئيسي
الوحدة 2 · الدرس 5 من 510/50 في الدورة~12 min
دروس الوحدة (5/5)

الأخطاء: النمط `if err != nil`

في Go، الأخطاء هي قيم وليست استثناءات. وظيفة يمكنها Fail يُرجع الخطأ باعتباره القيمة الأخيرة، ويقوم المتصل بالتحقق منها صراحة. إنه واضح، يمكن التنبؤ به، وسهل الاختبار – والثمن هو أكثر قليلا الإسهاب.

واجهة error

error عبارة عن واجهة صغيرة مدمجة في اللغة:

Go
type error interface {
    Error() string
}

أي نوع يقوم بتنفيذ Error() string هو error.

النمط الأساسي

Go
v, err := operazione()
if err != nil {
    // gestisci o propaga
    return err
}
// usa v

سوف ترى هذا آلاف المرات: إنه الرمز الاصطلاحي لكل شيء مكالمة غير معصومة. لا تشعر بالذنب تجاه التكرار، فهو ميزة، وليس كذلك خطأ.

أخطاء البناء: errors.New وfmt.Errorf

Go
import (
    "errors"
    "fmt"
)

err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)

fmt.Errorf مثالي عندما تريد تضمين متغيرات في الرسالة.

الالتفاف باستخدام %w

لنشر خطأ في إضافة السياق دون فقدان النص الأصلي:

Go
f, err := os.Open(path)
if err != nil {
    return fmt.Errorf("config: %w", err)
}

%w "يغلف" الخطأ الأصلي، ويمكن استرداده لاحقًا باستخدام errors.Is (المساواة للحراس) أو errors.As (لنوع الخرسانة):

Go
if errors.Is(err, os.ErrNotExist) {
    // file inesistente, gestione speciale
}

أخطاء الحارس

هذه هي الأخطاء التي تم تصديرها كمتغيرات، وتستخدم لإجراء مقارنات مع errors.Is:

Go
var ErrNotFound = errors.New("non trovato")

func find(id int) (Item, error) {
    // ...
    return Item{}, ErrNotFound
}

// chiamante:
if errors.Is(err, ErrNotFound) { ... }

panic و recover (معاينة)

panic موجود في Go ولكنه محجوز للأخطاء غير القابلة للاسترداد (مثل الأخطاء، الثوابت المنتهكة)، وليس لتدفق التحكم الطبيعي. سوف نتعمق أكثر وحدة الوظائف مع defer/recover. في الوقت الحالي: لا تستخدمه في مكانه للنمط if err != nil.

جربه

تمرين#go.m2.l5.e1
المحاولات: 0جارٍ التحميل…

قم بمعالجة الخطأ من strconv.Atoi: إذا أخطأت != nil، قم بطباعته ثم إرجاعه؛ خلاف ذلك طباعة ن.

جارٍ تحميل المحرر…
إظهار التلميح

النمط المتعارف عليه: تحقق من `err != nil`، وlog/return، ثم استخدم `n`.

الحل متاح بعد 3 من المحاولات

تمرين#go.m2.l5.e2
المحاولات: 0جارٍ التحميل…

قم بتنفيذ SafeDiv: إذا كان b == 0 قم بإرجاع 0 وخطأ.New('divisione per Zero'); وإلا أ/ب ولا شيء.

جارٍ تحميل المحرر…
إظهار التلميح

حدد `b == 0` قبل التقسيم لتجنب الذعر أثناء التشغيل.

الحل متاح بعد 3 من المحاولات

Quiz#go.m2.l5.e3
جاهز

ما هو النمط الاصطلاحي للتعامل مع الخطأ في Go؟

Go
v, err := f()
// poi?
خيارات الإجابة

خلاصة

  • error عبارة عن واجهة ذات أسلوب واحد Error() string.
  • النمط القانوني: v, err := f(); if err != nil { return err }.
  • إنشاء أخطاء في errors.New(msg) أو fmt.Errorf("ctx: %w", err).
  • استخدم %w للتغليف وerrors.Is / errors.As لفحص السلسلة.
  • panic فقط للأخطاء غير القابلة للاسترداد، وليس لتدفق التحكم العادي.