Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

واجهة fmt.Stringer

جزء من قسم Object Oriented Programming في رحلة 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()، ستظهر عملية الطباعة تنسيق الـ struct الافتراضي: {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}، ستحصل على مخرجات ذات معنى ومفهومة للمستخدمين.

ورقة مرجعية

تتحكم واجهة fmt.Stringer في كيفية ظهور الأنواع عند طباعتها:

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، يمكنك التحكم بدقة في كيفية تقديم النوع لنفسه، مما يجعل المخرجات أكثر وضوحاً وسهولة في الاستخدام.

جرّب بنفسك

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اختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming