סיכום – אוסף גנרי
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 72 מתוך 107.
אתגר
קלבואו נבנה מבנה נתונים גנרי של תור שמדגים את כל מה שלמדת על גנריות ב-Go! בניגוד למחסנית (LIFO), תור פועל לפי הסדר ראשון נכנס, ראשון יוצא (FIFO): הפריט הראשון שנוסף הוא הראשון שמוסר.
תארגן את הקוד שלך בשני קבצים:
queue.go: הגדר את אוסף התור הגנרי שלך.צור מבנה גנרי
Queue[T any]ששומר פריטים באופן פנימי. התור שלך צריך לתמוך בפעולות הבאות:Enqueue(item T)- מוסיפה פריט לסוף התורDequeue() (T, bool)- מסירה ומחזירה את הפריט שבראש התור, יחד עם ערך בוליאני שמציין הצלחה (החזר את ערך האפס ואתfalseאם התור ריק)Peek() (T, bool)- מחזירה את הפריט שבראש התור בלי להסיר אותו (אותה תבנית החזרה כמו ב-Dequeue)Size() int- מחזירה את מספר הפריטים בתורIsEmpty() bool- מחזירה true אם אין פריטים בתור
צור גם פונקציית בנאי
NewQueue[T any]() *Queue[T]שמחזירה מצביע לתור ריק ומאותחל.main.go: הדגם את התור שלך עם טיפוסים שונים בהתאם לקלט.קרא סמן טיפוס (
intאוstring), ואז קרא סדרת פקודות לביצוע בתור. כל פקודה מופיעה בשורה נפרדת:enqueue [value]- הוסף את הערך לתורdequeue- הסר והדפס את הפריט שבראש התור (הדפסemptyאם התור ריק)peek- הדפס את הפריט שבראש התור בלי להסיר אותו (הדפסemptyאם התור ריק)size- הדפס את הגודל הנוכחי
קרא פקודות עד שמתקבלת
done.
הקלטים הבאים יסופקו:
- שורה 1: סמן טיפוס (
intאוstring) - השורות הבאות: פקודות עד
done
לדוגמה, בהינתן:
int
enqueue 10
enqueue 20
enqueue 30
peek
dequeue
size
dequeue
dequeue
dequeue
doneהפלט שלך צריך להיות:
10
10
2
20
30
emptyובהינתן:
string
enqueue hello
enqueue world
size
peek
dequeue
peek
doneהפלט שלך צריך להיות:
2
hello
hello
worldהתור שלך צריך לפעול באופן זהה עבור טיפוסים של מספרים שלמים ומחרוזות, ולהדגים כיצד מימוש גנרי יחיד מטפל בכמה טיפוסים קונקרטיים תוך שמירה על בטיחות טיפוסים מלאה.
נסו בעצמכם
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// קרא את מציין הסוג
scanner.Scan()
typeIndicator := scanner.Text()
if typeIndicator == "int" {
// TODO: צור תור של מספרים שלמים באמצעות NewQueue[int]()
// עבד פקודות עבור תור המספרים השלמים
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: טפל בפקודות: enqueue, dequeue, peek, size
// עבור enqueue, המר את הערך ב-parts[1] למספר שלם
// עבור dequeue/peek, הדפס "empty" אם התור ריק
_ = command
}
} else if typeIndicator == "string" {
// TODO: צור תור של מחרוזות באמצעות NewQueue[string]()
// עבד פקודות עבור תור המחרוזות
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: טפל בפקודות: enqueue, dequeue, peek, size
// עבור enqueue, השתמש בערך המחרוזת מתוך parts[1]
// עבור dequeue/peek, הדפס "empty" אם התור ריק
_ = command
}
}
// אלה נמצאים כאן כדי למנוע שגיאות של ייבואים שאינם בשימוש במהלך הפיתוח
_ = strconv.Atoi
_ = fmt.Println
}
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP ב-Go
קבצים חיצונייםסביבת העבודה והמודולים של Goחבילות וייבואשמות מיוצאים לעומת שמות לא מיוצאיםמבוא ל-OOP ב-GoStructs כמחלקותהגדרת מתודות עבור Structsמקבלי Pointer לעומת Valueאתחול Structפונקציות Constructorחזרה – מחשבון פשוט4ממשקים
מבוא לממשקיםמימוש משתמעממשק כחוזהממשק ריק (any)אימות טיפוסמתג טיפוסיםהרכבת ממשקיםממשקי Stringer ו-Errorסיכום – מחשבון צורות7כימוס
שדות מיוצאים לעומת שדות לא מיוצאיםכימוס ברמת החבילהמתודות Getter ו-Setterהסתרת מידע ב-Goסיכום – רשומות תלמידים10Generics (Go 1.18 ומעלה)
מבוא ל־Genericsפרמטרים של טיפוסיםאילוצי טיפוסיםמבנים גנרייםפתרון עוקף למתודות גנריותסיכום – אוסף גנרי2העמקה בסוגים וב-Structs
סוגים בסיסיים ומורכביםהגדרות של סוגים מותאמים אישיתתגיות StructStructs אנונימייםStructs מקונניםערכי אפס וברירות מחדלסיכום – ספר אנשי קשר5קומפוזיציה במקום ירושה
למה ב-Go אין ירושהיסודות הטמעת Structקידום מתודותהטמעת כמה Structsהטמעה לעומת אגרגציההסתרת מתודות מוטמעותסיכום – היררכיית עובדים8טיפול בשגיאות ו-OOP
ממשק errorסוגי שגיאות מותאמים אישיתעטיפת שגיאות (fmt.Errorf)שגיאות Sentinelerrors.Is() ו-errors.As()Panic, Defer ו-Recoverסיכום – מנתח קבצים11ספרייה סטנדרטית ותכנות מונחה עצמים
io.Reader ו-io.Writersort.Interfaceהממשק fmt.Stringerencoding/json עם מבניםהממשק http.Handlerסיכום – מודלים של REST API3מצביעים וזיכרון
יסודות המצביעים ב-Goמצביעים למבניםהעברה לפי ערך לעומת לפי הפניההפונקציה new()איסוף אשפה ב-Goסיכום - בונה רשימה מקושרת6פולימורפיזם ב-Go
פולימורפיזם באמצעות ממשקיםטיפוס ברווז ב-Goכללי התאמה לממשקאוספים פולימורפייםהזרקת תלויותסיכום - מעבד תשלומים9מקביליות ו-OOP
יסודות GoroutinesChannels ותקשורתChannel עם חוצץ לעומת ללא חוצץפקודת Selectsync.Mutex ו-sync.RWMutexsync.WaitGroupתכנון Struct בטוח לשימוש במקבילסיכום - מאגר עובדים12מושגים מתקדמים בתכנות מונחה עצמים
דפוס האפשרויות הפונקציונליותדפוס Builder ב-Goשרשור מתודותכינויי טיפוסים לעומת הגדרותיסודות Reflectionסקירה כללית של יצירת קודתרגלו בעצמכם: קומפיילר Go אונליין