Menu
Coddy logo textTech

ממשקי Stringer ו-Error

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 32 מתוך 107.

הספרייה הסטנדרטית של Go מגדירה שני ממשקים שתשתמש בהם ללא הרף: fmt.Stringer ו-error. שניהם ממשקים פשוטים בעלי מתודה אחת, שמעניקים לטיפוסים שלך שילוב עוצמתי עם הפונקציונליות המובנית של Go.

הממשק Stringer נמצא בחבילה fmt ודורש שיטה אחת בלבד:

type Stringer interface {
    String() string
}

כשאתה מממש את String() בטיפוס שלך, פונקציות כמו fmt.Println משתמשות בו אוטומטית כדי להציג את הערך שלך:

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s (%d years old)", p.Name, p.Age)
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    fmt.Println(p)  // Alice (בת 30)
}

הממשק שגיאה פשוט באותה מידה, והוא דורש מתודה Error() שמחזירה מחרוזת:

type error interface {
    Error() string
}

כל טיפוס עם מתודה Error() יכול לשמש כערך שגיאה ב-Go. כך אפשר ליצור טיפוסי שגיאה מותאמים אישית עם הקשר נוסף:

type ValidationError struct {
    Field   string
    Message string
}

func (e ValidationError) Error() string {
    return fmt.Sprintf("%s: %s", e.Field, e.Message)
}

func main() {
    err := ValidationError{Field: "email", Message: "invalid format"}
    fmt.Println(err)  // email: invalid format
}

שני הממשקים האלה מדגימים את הפילוסופיה של Go: ממשקים קטנים וממוקדים שמאפשרים התנהגות רבת עוצמה באמצעות מימוש משתמע.

challenge icon

אתגר

קל

בואו נבנה מערכת לניטור טמפרטורה שמשתמשת גם בממשקים Stringer וגם error כדי לספק פלט קריא וטיפול משמעותי בשגיאות.

תארגנו את הקוד בשני קבצים:

  • temperature.go: צרו מבנה Temperature עם השדות Value (float64) ו-Unit (string). ממשו את המתודה String() כך שבעת הדפסה היא תציג את הטמפרטורה בפורמט קריא. צרו גם מבנה TemperatureError עם השדות Temp (float64) ו-Reason (string), וממשו את המתודה Error() כדי לספק הודעות שגיאה תיאוריות.
  • main.go: צרו פונקציה בשם ValidateTemperature שמקבלת Temperature ומחזירה שגיאה אם הטמפרטורה אינה תקינה. טמפרטורה אינה תקינה אם היא נמוכה מאפס מוחלט (-273.15 עבור צלזיוס, -459.67 עבור פרנהייט). אם הטמפרטורה תקינה, הפונקציה מחזירה nil. קראו נתוני טמפרטורה מהקלט, צרו מופע של Temperature, אמתו אותו והדפיסו פלט מתאים.

הקלטים הבאים יסופקו:

  • שורה 1: ערך הטמפרטורה (float)
  • שורה 2: יחידה (C עבור צלזיוס או F עבור פרנהייט)

המתודה String() שלכם צריכה להחזיר את הפורמט:

[Value] degrees [Unit]

כאשר Unit היא המילה המלאה "Celsius" או "Fahrenheit", בהתאם לקלט.

המתודה Error() שלכם צריכה להחזיר את הפורמט:

invalid temperature [Temp]: [Reason]

אם הטמפרטורה תקינה, הדפיסו את Temperature באמצעות fmt.Println (שישתמש במתודה String() שלכם). אם היא אינה תקינה, הדפיסו את השגיאה (שתשתמש במתודה Error() שלכם).

לדוגמה, עבור 25.5 ו-C, הפלט שלכם צריך להיות:

25.5 degrees Celsius

עבור -500 ו-F, הפלט שלכם צריך להיות:

invalid temperature -500: below absolute zero

השתמשו ב-"below absolute zero" בתור הסיבה כאשר הטמפרטורה נמוכה מדי.

REQUIRED OUTPUT FORMAT: [Your translated content here]

נסו בעצמכם

package main

import (
	"fmt"
)

// ValidateTemperature בודקת אם הטמפרטורה תקינה
// מחזירה שגיאה אם הטמפרטורה נמוכה מהאפס המוחלט
// האפס המוחלט: -273.15 בסולם צלזיוס, -459.67 בסולם פרנהייט
func ValidateTemperature(t Temperature) error {
	// TODO: יש לממש את לוגיקת האימות
	// בדקו אם הטמפרטורה נמוכה מהאפס המוחלט בהתאם ליחידת המידה
	// החזירו TemperatureError אם הטמפרטורה אינה תקינה, ו־nil אם היא תקינה
	return nil
}

func main() {
	var value float64
	var unit string
	fmt.Scanln(&value)
	fmt.Scanln(&unit)

	// TODO: צרו מבנה Temperature עם ערכי הקלט

	// TODO: אמתו את הטמפרטורה באמצעות ValidateTemperature

	// TODO: אם יש שגיאה, הדפיסו אותה
	// אחרת, הדפיסו את הטמפרטורה (תוך שימוש במתודה String())
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Go אונליין