Menu
Coddy logo textTech

encoding/json עם מבנים

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

החבילה encoding/json מאפשרת לך להמיר מבני Go ל-JSON ולהפך. זה חיוני לממשקי API, לקובצי תצורה ולאחסון נתונים. תגיות של מבנים קובעות כיצד שדות ממופים למפתחות JSON.

כדי להמיר struct ל-JSON, השתמשו ב-json.Marshal:

type User struct {
    Name  string `json:"name"`
    Email string `json:"email"`
    Age   int    `json:"age"`
}

func main() {
    user := User{Name: "Alice", Email: "alice@example.com", Age: 30}
    data, _ := json.Marshal(user)
    fmt.Println(string(data))
    // {"name":"Alice","email":"alice@example.com","age":30}
}

תגיות המבנה כמו `json:"name"` מציינות את שמות המפתחות ב-JSON. ללא תגיות, Go משתמש ישירות בשם השדה. רק שדות מיוצאים (שמתחילים באות גדולה) נכללים בפלט ה-JSON.

כדי להמיר JSON בחזרה למבנה, השתמשו ב־json.Unmarshal:

jsonStr := `{"name":"Bob","email":"bob@example.com","age":25}`
var user User
json.Unmarshal([]byte(jsonStr), &user)
fmt.Println(user.Name)  // Bob

אפשרויות תגית נפוצות כוללות את omitempty כדי לדלג על ערכי אפס ואת - כדי להתעלם משדה לחלוטין:

type Product struct {
    ID       int    `json:"id"`
    Name     string `json:"name"`
    Price    float64 `json:"price,omitempty"`
    Internal string `json:"-"`
}

עם omitempty, אם Price הוא אפס, הוא לא יופיע ב-JSON. השדה Internal לעולם אינו נכלל, ללא קשר לערכו.

challenge icon

אתגר

קל

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

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

  • movie.go: הגדירו את מודל הנתונים של הסרט עם תגיות JSON מתאימות.

    צרו מבנה Movie עם השדות והמיפויים ל-JSON הבאים:

    • Title (מחרוזת) ממופה ל-"title"
    • Director (מחרוזת) ממופה ל-"director"
    • Year (מספר שלם) ממופה ל-"year"
    • Rating (מספר ממשי מסוג float64) ממופה ל-"rating" עם omitempty, כך שסרטים ללא דירוג לא יציגו שדה דירוג
    • יש להחריג את InternalID (מחרוזת) לחלוטין מ-JSON באמצעות "-"

    צרו פונקציה ToJSON(m Movie) string שממירה Movie למחרוזת JSON. צרו גם את FromJSON(jsonStr string) Movie, שמנתחת מחרוזת JSON בחזרה למבנה Movie.

  • main.go: הדגימו המרת JSON בשני הכיוונים.

    קראו סוג פעולה (encode או decode).

    עבור encode: קראו את פרטי הסרט (כותרת, במאי, שנה, דירוג) בשורות נפרדות. צרו Movie עם InternalID שערכו "internal-123", המירו אותו ל-JSON והדפיסו את התוצאה.

    עבור decode: קראו מחרוזת JSON, המירו אותה למבנה Movie והדפיסו את פרטי הסרט בפורמט הבא:

    Title: [title]
    Director: [director]
    Year: [year]
    Rating: [rating]

    הציגו את הדירוג עם ספרה אחת אחרי הנקודה העשרונית. אם הדירוג הוא 0 (אינו מופיע ב-JSON), הדפיסו Rating: N/A במקום זאת.

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

  • שורה 1: סוג פעולה (encode או decode)
  • עבור encode: כותרת, במאי, שנה, דירוג (ארבע שורות)
  • עבור decode: מחרוזת JSON (שורה אחת)

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

encode
Inception
Christopher Nolan
2010
8.8

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

{"title":"Inception","director":"Christopher Nolan","year":2010,"rating":8.8}

שימו לב ש-InternalID לא מופיע בפלט בגלל התגית "-".

ובהינתן:

encode
The Matrix
Wachowskis
1999
0

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

{"title":"The Matrix","director":"Wachowskis","year":1999}

שימו לב ש-rating מושמט משום שהוא אפס ויש לו omitempty.

ובהינתן:

decode
{"title":"Interstellar","director":"Christopher Nolan","year":2014,"rating":8.6}

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

Title: Interstellar
Director: Christopher Nolan
Year: 2014
Rating: 8.6

ובהינתן:

decode
{"title":"Tenet","director":"Christopher Nolan","year":2020}

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

Title: Tenet
Director: Christopher Nolan
Year: 2020
Rating: N/A

נסו בעצמכם

package main

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

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

	// קרא את סוג הפעולה
	operation, _ := reader.ReadString('\n')
	operation = strings.TrimSpace(operation)

	if operation == "encode" {
		// קרא את פרטי הסרט
		title, _ := reader.ReadString('\n')
		title = strings.TrimSpace(title)

		director, _ := reader.ReadString('\n')
		director = strings.TrimSpace(director)

		yearStr, _ := reader.ReadString('\n')
		yearStr = strings.TrimSpace(yearStr)
		year, _ := strconv.Atoi(yearStr)

		ratingStr, _ := reader.ReadString('\n')
		ratingStr = strings.TrimSpace(ratingStr)
		rating, _ := strconv.ParseFloat(ratingStr, 64)

		// TODO: צור struct מסוג Movie עם הערכים שנקראו
		// הגדר את InternalID ל-"internal-123"
		// המר ל-JSON באמצעות ToJSON והדפס את התוצאה

	} else if operation == "decode" {
		// קרא מחרוזת JSON
		jsonStr, _ := reader.ReadString('\n')
		jsonStr = strings.TrimSpace(jsonStr)

		// TODO: המר JSON ל-Movie באמצעות FromJSON
		// הדפס את פרטי הסרט בפורמט הנדרש
		// השתמש ב-fmt.Sprintf("%.1f", rating) כדי לעצב את rating
		// אם rating הוא 0, הדפס במקום זאת "Rating: N/A"

	}
}
quiz iconבחנו את עצמכם

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

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

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