Menu
Coddy logo textTech

יסודות הטמעת Struct

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

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

הנה התחביר הבסיסי:

type Address struct {
    City    string
    Country string
}

type Person struct {
    Name string
    Address  // מוטמע - ללא שם שדה
}

כשמטמיעים את Address בתוך Person, אפשר לגשת ישירות לשדות המוטמעים במבנה החיצוני:

func main() {
    p := Person{
        Name: "Alice",
        Address: Address{
            City:    "London",
            Country: "UK",
        },
    }
    
    fmt.Println(p.City)     // London - גישה ישירה
    fmt.Println(p.Country)  // UK - גישה ישירה
    fmt.Println(p.Address.City)  // גם עובד
}

שימו לב כיצד p.City עובד בלי לכתוב במפורש p.Address.City. ‏Go מקדמת אוטומטית את השדות של המבנה המוטמע, וכך הם נגישים כאילו השתייכו למבנה החיצוני. עדיין אפשר לגשת אליהם דרך שם הטיפוס המוטמע כשצריך.

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

challenge icon

אתגר

קל

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

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

  • vehicle.go: צרו שני structs שפועלים יחד באמצעות הטמעה:
    • struct בשם ContactInfo עם השדות OwnerName ו-Phone (שניהם מחרוזות)
    • struct בשם Vehicle שמטמיע את ContactInfo (ללא שם שדה) ומוסיף שדות משלו: Make, Model ו-Year
    צרו גם מתודה בשם Summary עבור Vehicle, שמחזירה מחרוזת מעוצבת הכוללת את כל פרטי הרכב ופרטי יצירת הקשר.
  • main.go: קראו את פרטי הרכב והבעלים מהקלט, צרו מופע של Vehicle עם ContactInfo מוטמע, והדגימו גישה לשדות המוטמעים הן ישירות והן דרך שם הטיפוס המוטמע. הדפיסו את סיכום הרכב בסוף.

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

  • שורה 1: שם הבעלים
  • שורה 2: מספר טלפון
  • שורה 3: יצרן הרכב
  • שורה 4: דגם הרכב
  • שורה 5: שנה (מספר שלם)

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

[Year] [Make] [Model] - Owner: [OwnerName], Phone: [Phone]

בקובץ הראשי שלכם, הדגימו קידום שדות באמצעות הדפסה של:

  1. שם הבעלים שניגשים אליו ישירות מתוך Vehicle (לדוגמה, v.OwnerName)
  2. מספר הטלפון שניגשים אליו דרך הטיפוס המוטמע (לדוגמה, v.ContactInfo.Phone)
  3. הסיכום המלא באמצעות המתודה Summary שלכם

לדוגמה, עבור Alice Smith, 555-1234, Toyota, Camry ו-2023, הפלט שלכם צריך להיות:

Alice Smith
555-1234
2023 Toyota Camry - Owner: Alice Smith, Phone: 555-1234

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

נסו בעצמכם

package main

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

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

	// קראו את שם הבעלים
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)

	// קראו את מספר הטלפון
	phone, _ := reader.ReadString('\n')
	phone = strings.TrimSpace(phone)

	// קראו את יצרן הרכב
	make, _ := reader.ReadString('\n')
	make = strings.TrimSpace(make)

	// קראו את דגם הרכב
	model, _ := reader.ReadString('\n')
	model = strings.TrimSpace(model)

	// קראו את שנת הייצור
	yearStr, _ := reader.ReadString('\n')
	yearStr = strings.TrimSpace(yearStr)
	year, _ := strconv.Atoi(yearStr)

	// TODO: צרו מופע של Vehicle עם ContactInfo מוטמע
	// השתמשו בערכים שנקראו מהקלט למעלה

	// TODO: הדפיסו את שם הבעלים באמצעות גישה ישירה דרך Vehicle (קידום שדות)
	// דוגמה: fmt.Println(v.OwnerName)

	// TODO: הדפיסו את מספר הטלפון באמצעות גישה דרך שם הטיפוס המוטמע
	// דוגמה: fmt.Println(v.ContactInfo.Phone)

	// TODO: הדפיסו את הסיכום המלא באמצעות המתודה Summary
	// דוגמה: fmt.Println(v.Summary())

	// הסירו את השורות האלה לאחר שתממשו את הפתרון
	_ = ownerName
	_ = phone
	_ = make
	_ = model
	_ = year
}
quiz iconבחנו את עצמכם

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

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

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