דילוג לתוכן המרכזי
מודול 8 · שיעור 1 מתוך 536/50 בקורס~10 min
שיעורי מודול (1/5)

`fmt` מתקדם

החבילה fmt היא השער לכל I/O טקסטואליים ב-Go. לדעת זאת היטב פירושו כתיבת יומנים קריאים, שגיאות אינפורמטיביות ועיצוב ערכי באופן אידיומטי מבלי להזדקק לספריות חיצוניות.

ארבע המשפחות

fmt חושף פונקציות בארבע משפחות, המובחן על ידי קידומת:

  • Print* → כותב אל os.Stdout (Print, Println, Printf).
  • Fprint* → כותב לכל io.Writer (Fprintln(os.Stderr, ...), Fprintf(file, ...)).
  • Sprint* → מחזירה מחרוזת ללא הדפסה (Sprintf, Sprintln).
  • Errorf → בונה error בפורמט.
Go
fmt.Println("hello")                       // stdout
fmt.Fprintln(os.Stderr, "boom")            // stderr
s := fmt.Sprintf("[%d]", 42)               // "[42]"
err := fmt.Errorf("parse %q: %w", in, base) // wrapped error

ההבדל בין Print ל-Println הוא רק הרווח בין ארגומנטים לשורה החדשה הנגררת: Println תמיד מוסיף \n, Print הפורמט Print לא עוקב אחר הפורמט של Print.

פעלים עיקריים

פועלמה זה עושה
%vערך ברירת מחדל (קורא String() אם מיושם).
%+vמבנה עם שמות שדות.
%#vתחביר Go (שימושי עבור איתור באגים ותמונות מצב).
%Tסוג דינמי של הערך.
%dמספר שלם בבסיס 10.
%b %o %x %Xבינארי, אוקטלי, הקסדצימלי (אותיות קטנות/רישיות).
%f %e %gנקודה צפה: קבועה, אקספוננציאלית, קומפקטית.
%sמחרוזת (או error/Stringer).
%qמחרוזת מצוטטת בסגנון Go (כלולות בריחות).
%cתו Unicode (rune).
%pמצביע בהקסדצימלי.
%wמעטפת שגיאה (רק בתוך Errorf).
Go
type Point struct{ X, Y int }
p := Point{1, 2}
fmt.Printf("%v\n", p)   // {1 2}
fmt.Printf("%+v\n", p)  // {X:1 Y:2}
fmt.Printf("%#v\n", p)  // main.Point{X:1, Y:2}
fmt.Printf("%T\n", p)   // main.Point

רוחב, דיוק, דגלים

פעלים מספריים ומיתרים מקבלים רוחב ודיוק:

  • %6d → רוחב מינימלי 6, ריפוד שמאלי עם רווחים.
  • %-6d → רוחב 6, ריפוד ימני (דגל -).
  • %06d → רוחב 6, ריפוד עם 0 (דגל 0).
  • %.2f → דיוק 2 ספרות עשרוניות.
  • %8.2f → רוחב 8, דיוק 2.
Go
fmt.Printf("|%6d|\n", 42)    // |    42|
fmt.Printf("|%-6d|\n", 42)   // |42    |
fmt.Printf("|%06d|\n", 42)   // |000042|
fmt.Printf("|%8.2f|\n", 3.14)// |    3.14|

עבור טבלאות מיושרות, רוחב קבוע + %-...s עבור עמודות טקסט הוא הדפוס הפשוט ביותר לפני המעבר ל-text/tabwriter.

%w וגלישת שגיאה

%w הוא מיוחד: הוא עובד רק בתוך fmt.Errorf ושומר על השגיאה המקורית בשרשרת, כך שerrors.Is וerrors.As יוכלו ללכת בה.

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

שימוש ב-%v במקום ב-%w מדפיס את הודעת השגיאה אך מפרק את השרשרת: אין פתיחה, אין errors.Is. כלל: אם אתה רוצה שהמתקשר יוכל להבחין בסוג השגיאה או בזהות, השתמש ב-%w (רק אחד לכל Errorf).

תרגילים

פעילות גופנית#go.m8.l1.e1
ניסיונות: 0טוען...

השתמש ב-fmt.Sprintf כדי לעצב את המחרוזת '[42]' מהמספר השלם 42, ואז הדפס אותה.

טוען עורך...

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

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

הדפס את ה-struct p עם הפועל %+v (הוא חייב לכלול את שמות השדות).

טוען עורך...

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

Quiz#go.m8.l1.e3
מוכן

איזה פועל, בשימוש ב-fmt.Errorf, משמר את שרשרת השגיאות עבור errors.Is/As?

Go
err := fmt.Errorf("read %q: ???", path, base)
אפשרויות תשובה