דילוג לתוכן המרכזי
מודול 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: אם שגיאה != אפס, הדפס אותה והחזר; אחרת הדפס נ.

טוען עורך...
הצג רמז

הדפוס הקנוני: סמן 'err != nil', log/return, ואז השתמש ב-'n'.

הפתרון זמין לאחר 3 ניסיונות

פעילות גופנית#go.m2.l5.e2
ניסיונות: 0טוען...

יישם safeDiv: אם b == 0 החזר 0 ו- errors.New('divisione per zero'); אחרת a/b ואפס.

טוען עורך...
הצג רמז

סמן את '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 רק עבור שגיאות בלתי ניתנות לשחזור, לא עבור זרימת בקרה רגילה.