Menu
Coddy logo textTech

ממשק ריק (any)

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

ממשק ריק הוא ממשק שאין בו מתודות. מכיוון שלכל טיפוס ב-Go יש לפחות אפס מתודות, כל טיפוס מקיים אוטומטית את הממשק הריק. לכן הוא יכול להכיל ערכים מכל טיפוס.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

החל מ-Go 1.18, מילת המפתח any הוצגה ככינוי ל-interface{}. הם ניתנים להחלפה לחלוטין, אבל קל יותר לקרוא את any.

var value any = "Go is awesome"

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

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

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

אי אפשר לקרוא ישירות למתודות או לגשת לשדות בלי לחלץ תחילה את הטיפוס הבסיסי. בשיעורים הבאים נלמד כיצד לשלוף את הטיפוס הממשי מתוך ממשק ריק באמצעות הצהרות טיפוס ומתגי טיפוס.

challenge icon

אתגר

קל

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

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

  • box.go: הגדירו מבנה Box עם שדה יחיד Content מסוג any. צרו פונקציית בנאי NewBox שמקבלת ערך מכל סוג ומחזירה מצביע ל-Box שמכיל את הערך הזה. הוסיפו מתודה Describe שמחזירה מחרוזת המציגה מה מאוחסן בקופסה.
  • main.go: קראו ערכים שונים מהקלט, צרו קופסאות שמכילות מספר שלם, מחרוזת וערך בוליאני, ואז הדפיסו את התיאור של כל קופסה כדי להראות כיצד אותו סוג Box יכול להכיל ערכים שונים לחלוטין.

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

  • שורה 1: ערך של מספר שלם
  • שורה 2: ערך מחרוזת
  • שורה 3: ערך בוליאני (true או false)

המתודה Describe שלכם צריכה להחזיר מחרוזת בפורמט הבא:

Box contains: [value]

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

Box contains: 42
Box contains: hello
Box contains: true

התובנה המרכזית כאן היא שמבנה Box יחיד יכול לאחסן מספר שלם, מחרוזת או ערך בוליאני: כל זאת משום שהטיפוס any מקבל ערכים מכל סוג. כל קופסה מכילה משהו אחר, ובכל זאת כולן מאותו סוג Box.

נסו בעצמכם

package main

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

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

	// קרא ערך שלם
	line1, _ := reader.ReadString('\n')
	intVal, _ := strconv.Atoi(strings.TrimSpace(line1))

	// קרא ערך מחרוזת
	line2, _ := reader.ReadString('\n')
	strVal := strings.TrimSpace(line2)

	// קרא ערך בוליאני
	line3, _ := reader.ReadString('\n')
	boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))

	// TODO: צור תיבות לכל ערך באמצעות NewBox
	// TODO: הדפס את התיאור של כל תיבה באמצעות המתודה Describe

	// השתמש במשתנים כדי למנוע שגיאות קומפילציה (הסר שורות אלה בעת המימוש)
	_ = intVal
	_ = strVal
	_ = boolVal

	// דוגמה לפורמט הפלט:
	// fmt.Println(box.Describe())
}
quiz iconבחנו את עצמכם

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

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

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