0Pricing
Go Academy · درس

واجهة Stringer

خصّص طريقة طباعة الأنواع

واجهة Stringer درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.

طباعة البنية الافتراضية

تعرض طباعة البنية باستخدام %v حقولها الخام افتراضيًا. وهذا مناسب لتصحيح الأخطاء، لكنه ليس سهل القراءة دائمًا.

package main

import "fmt"

type Color struct{ R, G, B int }

func main() {
    c := Color{255, 0, 0}
    fmt.Println(c)
}

واجهة Stringer

تحتوي واجهة fmt.Stringer على دالة واحدة:

  • String() string

وأي نوع يعرّفها يتحكم في كيفية ظهوره عند طباعته.

package main

import "fmt"

type Greeting struct{ Name string }

func (g Greeting) String() string {
    return "Hello, " + g.Name
}

func main() {
    fmt.Println(Greeting{"Ada"})
}

تُستخدم تلقائيًا

عندما يحتوي نوع ما على دالة String()، تستدعيها Println وPrintf مع %v أو %s والدوال المشابهة تلقائيًا.

package main

import "fmt"

type Greeting struct{ Name string }

func (g Greeting) String() string {
    return "Hi " + g.Name
}

func main() {
    g := Greeting{"Bob"}
    fmt.Printf("%s and %v\n", g, g)
}

التنسيق داخل String()

أنشئ النتيجة باستخدام fmt.Sprintf لإنتاج تمثيل مخصص ومنظم.

package main

import "fmt"

type Color struct{ R, G, B int }

func (c Color) String() string {
    return fmt.Sprintf("rgb(%d, %d, %d)", c.R, c.G, c.B)
}

func main() {
    fmt.Println(Color{255, 128, 0})
}

Stringer مع الأنواع المسماة

لا تقتصر Stringer على البنى. فأي نوع مسمى، حتى النوع المبني على int، يمكنه تنفيذها. وهذا هو النمط التقليدي للتعدادات.

package main

import "fmt"

type Day int

func (d Day) String() string {
    names := []string{"Mon", "Tue", "Wed"}
    return names[d]
}

func main() {
    fmt.Println(Day(1))
}

تعدادات تُطبع بشكل جيد

اجمع بين iota وStringer لكي تُطبع الثوابت كأسماء سهلة القراءة بدلًا من أرقام.

package main

import "fmt"

type State int

const (
    Idle State = iota
    Running
    Done
)

func (s State) String() string {
    return []string{"Idle", "Running", "Done"}[s]
}

func main() {
    fmt.Println(Running)
}

مستقبِل القيمة مقابل مستقبِل المؤشر

إذا استخدمت String() مستقبِل قيمة، فستُطبع القيم والمؤشرات بشكل جيد. أما مع مستقبِل مؤشر، فلن تُفعّلها إلا المؤشرات.

package main

import "fmt"

type Tag struct{ Name string }

func (t Tag) String() string { return "#" + t.Name }

func main() {
    t := Tag{"go"}
    fmt.Println(t)
    fmt.Println(&t)
}

تجنّب الاستدعاء التكراري اللانهائي

لا تستدعِ fmt.Sprintf("%v", t) على النوع نفسه داخل String() الخاص به. فهذا يستدعي String() مجددًا إلى ما لا نهاية. نسّق الحقول مباشرةً.

package main

import "fmt"

type Money struct{ Cents int }

func (m Money) String() string {
    return fmt.Sprintf("$%.2f", float64(m.Cents)/100)
}

func main() {
    fmt.Println(Money{1050})
}

Stringer في الشرائح

عند طباعة شريحة من قيم Stringer، تُنسّق كل قيمة باستخدام دالة String() الخاصة بها.

package main

import "fmt"

type Tag struct{ Name string }

func (t Tag) String() string { return "#" + t.Name }

func main() {
    tags := []Tag{{"go"}, {"web"}}
    fmt.Println(tags)
}

استخدامها كواجهة

يمكنك تخزين أي Stringer في متغير من النوع fmt.Stringer واستدعاء String() عبر الواجهة.

package main

import "fmt"

type City struct{ Name string }

func (c City) String() string { return "City of " + c.Name }

func main() {
    var s fmt.Stringer = City{"Oslo"}
    fmt.Println(s.String())
}

أهميتها

يمنح تنفيذ Stringer أنواعك مخرجًا منظمًا في كل مكان تُطبع فيه أو تُسجّل، من دون الحاجة إلى شيفرة تنسيق إضافية في كل موضع استدعاء.

package main

import "fmt"

type Temp float64

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

func main() {
    fmt.Println(Temp(21.5))
}

تحقق سريع

ما الدالة التي يجب أن يعرّفها النوع ليستوفي fmt.Stringer؟

مراجعة: واجهة Stringer

تعلّمت تخصيص الطباعة:

  • نفّذ String() string لاستيفاء fmt.Stringer.
  • تستدعيها fmt تلقائيًا مع %v و%s.
  • وهي مفيدة جدًا للتعدادات؛ وتجنّب استخدام %v بشكل تكراري على النوع نفسه.
package main

import "fmt"

type Level int

func (l Level) String() string {
    return []string{"low", "mid", "high"}[l]
}

func main() {
    fmt.Println(Level(2))
}

الأسئلة الشائعة

هل درس «واجهة Stringer» مجاني؟

نعم — نص درس «واجهة Stringer» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.

ماذا ستتعلم في «واجهة Stringer»؟

خصّص طريقة طباعة الأنواع تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟

لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «واجهة Stringer»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟

نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. أحرف تنسيق Printf
  2. Sprintf وFprintf
  3. واجهة Stringer
  4. مسح الإدخال
← العودة إلى Go Academy