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

واجهة الخطأ

error في Go ليست كلمة رئيسية: إنها واجهة مضمنة بها طريقة واحدة.

Go
type error interface {
    Error() string
}

أي شيء يحتوي على Error() string هو error. جنبا إلى جنب مع اتفاقية إرجاع (T, error) من الوظائف، إنها أساس معالجة الأخطاء في Go.

أخطاء الحارس

Go
import "errors"

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

func find(key string) (string, error) {
    // ...
    return "", ErrNotFound
}

الحارس هو قيمة error المصدرة والتي يمكن للمتصل الوصول إليها المقارنة للتعرف على حالة خطأ محددة.

الأخطاء المخصصة (مع البيانات)

لحمل السياق (مثل المفتاح المفقود)، يمكنك تحديد نوع:

Go
type ErrNotFound struct {
    Key string
}

func (e *ErrNotFound) Error() string {
    return "non trovato: " + e.Key
}

func find(key string) (string, error) {
    return "", &ErrNotFound{Key: key}
}

الأخطاء.هي والأخطاء.كما (الذهاب 1.13+)

المقارنة مع == لا تعمل إلا مع الحراس "الخالصين". أن تكون قوية ضد الأخطاء الملتفة، استخدم الحزمة errors:

Go
import "errors"

if errors.Is(err, ErrNotFound) {
    // err IS ErrNotFound (even if wrapped)
}

var nfe *ErrNotFound
if errors.As(err, &nfe) {
    // err IS (or wraps) an *ErrNotFound; nfe points to the concrete value
    fmt.Println("chiave mancante:", nfe.Key)
}
  • errors.Is(err, target): صحيح إذا كان الهدف موجودًا في مكان ما في سلسلة التغليف.
  • errors.As(err, &target): يتم تعيينه لاستهداف الخطأ الأول في السلسلة من نوعها.

الالتفاف بـ %w

Go
if err := find("k"); err != nil {
    return fmt.Errorf("operazione X: %w", err)
}

%w (NOT %s أو %v) ينشئ خطأً جديدًا يلتف الأصلي، مع إبقاء السلسلة قابلة للتنقل بواسطة errors.Is/As.

نمط التعامل

Go
v, err := op()
if err != nil {
    return fmt.Errorf("op fallita per %q: %w", id, err)
}

التعابير:

  • تحقق من err != nil على الفور، لا يوجد "مسار سعيد مبكر".
  • أضف سياقًا على كل مستوى باستخدام fmt.Errorf("... : %w", err).
  • "المنبع" (بالقرب من الرئيسي/المعالج)، قم بالتمييز باستخدام errors.Is/As.

جربه

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

قم بتطبيق سلسلة Error() على *ErrNotFound بحيث تُرجع "non trovato: <Key>".

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

`fmt.Println(err)` يستدعي تلقائيًا طريقة Error() في البنية الخاصة بك.

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

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

استخدم Errors.Is للتحقق مما إذا كان الخطأ يساوي الحارس ErrVuoto.

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

`errors.Is(err, target)` قوي حتى مع سلاسل التغليف.

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

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

ما هو التوقيع الدقيق لطريقة تنفيذ الخطأ؟

Go
func (e *MyErr) ??? {}
خيارات الإجابة

خلاصة

  • error = interface { Error() string }، مدمج.
  • الحراس مع errors.New("...") للحالات المعروفة بدون سياق.
  • أنواع الأخطاء المخصصة مع الحقول التي تحمل السياق.
  • errors.Is(err, target): مقارنة قوية بالالتفاف.
  • errors.As(err, &target): استخراج نوع الخرسانة.
  • fmt.Errorf("...: %w", err): غلاف يحفظ السلسلة.
  • لا تستخدم أبدًا %v / %s للالتفاف: استخدم دائمًا %w.