Menu
Coddy logo textTech

הממשק fmt.Stringer

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

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

type Stringer interface {
    String() string
}

כשמעבירים ערך אל fmt.Println, אל fmt.Printf עם %v, או לפונקציות דומות, Go בודקת אם הטיפוס מממש את Stringer. אם כן, Go קוראת למתודה String() כדי לקבל את ייצוג הטקסט.

type Temperature struct {
    Celsius float64
}

func (t Temperature) String() string {
    return fmt.Sprintf("%.1f°C", t.Celsius)
}

func main() {
    temp := Temperature{Celsius: 23.5}
    fmt.Println(temp)  // 23.5°C
}

ללא המתודה String(), הפלט היה מציג את מבנה ברירת המחדל: {23.5}. באמצעות מימוש Stringer, אפשר לשלוט בדיוק באופן שבו הטיפוס שלך מוצג.

הדבר שימושי במיוחד עבור טיפוסים שבהם ערכי השדות הגולמיים אינם מעבירים את המשמעות בבירור. טיפוס Duration עשוי להציג "2h 30m" במקום להציג ננו־שניות גולמיות, או שטיפוס User עשוי להציג שם בפורמט מעוצב במקום את כל השדות שלו.

challenge icon

אתגר

קל

בואו נבנה מערכת למעקב אחר זמן שמציגה משכי זמן בפורמט ידידותי לאנשים! תממשו את הממשק fmt.Stringer כדי לקבוע איך הטיפוסים המותאמים אישית שלכם יוצגו בעת הדפסה.

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

  • duration.go: הגדירו טיפוסים הקשורים לזמן עם ייצוגי מחרוזת מותאמים אישית.

    צרו מבנה Duration ששומר את המספר הכולל של הדקות כמספר שלם. ממשו את המתודה String() כך שבעת הדפסה, הערך יוצג בפורמט קריא, כמו 2h 30m עבור 150 דקות, או 0h 45m עבור 45 דקות. יש להציג תמיד את השעות ואת הדקות.

    צרו מבנה Task עם שדות עבור Name (מחרוזת) ו-Time (Duration). ממשו את String() עבור Task כדי להציג בפורמט [Name]: [duration], כאשר משך הזמן משתמש במתודת String משלו.

  • main.go: בנו והציגו משימות עם משכי הזמן שלהן.

    קראו את מספר המשימות, ואז עבור כל משימה קראו את שמה ואת משכה בדקות. צרו מופעים של Task והדפיסו כל אחד מהם ישירות באמצעות fmt.Println: הממשק Stringer יטפל בעיצוב באופן אוטומטי.

    לאחר הדפסת כל המשימות, חשבו והדפיסו את הזמן הכולל של כל המשימות בפורמט:

    Total: [duration]

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

  • שורה 1: מספר המשימות
  • השורות הבאות: שם המשימה ומספר הדקות (שתי שורות לכל משימה)

לדוגמה, בהינתן:

3
Code Review
90
Meeting
45
Documentation
120

הפלט שלכם צריך להיות:

Code Review: 1h 30m
Meeting: 0h 45m
Documentation: 2h 0m
Total: 4h 15m

ובהינתן:

2
Design
180
Testing
65

הפלט שלכם צריך להיות:

Design: 3h 0m
Testing: 1h 5m
Total: 4h 5m

באמצעות מימוש Stringer, הטיפוסים שלכם משתלבים בצורה חלקה עם פונקציות ההדפסה של Go. במקום לראות שדות גולמיים של מבנים כמו {90}, תקבלו פלט בעל משמעות שמובן למשתמשים.

נסו בעצמכם

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// קרא את מספר המשימות
	line, _ := reader.ReadString('\n')
	numTasks, _ := strconv.Atoi(strings.TrimSpace(line))

	// TODO: צור slice לאחסון המשימות
	// TODO: עקוב אחר סך הדקות

	for i := 0; i < numTasks; i++ {
		// קרא את שם המשימה
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		// קרא את משך המשימה בדקות
		minutesLine, _ := reader.ReadString('\n')
		minutes, _ := strconv.Atoi(strings.TrimSpace(minutesLine))

		// TODO: צור Task עם השם ו-Duration
		// TODO: הדפס את המשימה (fmt.Println ישתמש בממשק Stringer)
		// TODO: הוסף את הדקות לסך הכול
		_ = name
		_ = minutes
	}

	// TODO: הדפס את המשך הכולל בפורמט "Total: Xh Ym"
}
quiz iconבחנו את עצמכם

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

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

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