שיעורי מודול (2/5)
שיטות: ערך מול מקלט מצביע
שיטה ב-Go היא פונקציה עם מקלט: מיוחד
פרמטר שהוכרז בין func לשם השיטה, המחייב את
שיטה לסוג. אין מחלקות: ניתן להגדיר שיטות על
כל סוג שמוכרז בחבילה הנוכחית.
תַחבִּיר
type Person struct {
Name string
}
func (p Person) Greet() string {
return "ciao " + p.Name
}
p := Person{Name: "Ada"}
fmt.Println(p.Greet()) // "ciao Ada"המקלט p Person הופך את Greet לשיטה של Person. בתוך ה
שיטה, p הוא משתנה כמו כל משתנה אחר.
מקלט ערך מול מקלט מצביע
// VALUE receiver: operates on a COPY of the value
func (p Person) NameUpper() string {
return strings.ToUpper(p.Name)
}
// POINTER receiver: operates on the original value, can mutate it
func (p *Person) Rename(n string) {
p.Name = n
}עם מקלט מצביע ניתן לשנות את המקלט ואת השינויים נראים מחוץ לשיטה. עם מקבל ערך אתה לא יכול - היית שנה רק את העותק המקומי.
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name) // "Grace" — change is visibleמתי להשתמש במקלט מצביע
כללים מעשיים, לפי סדר עדיפות:
- עליך לשנות את המקלט → מקלט מצביע. הֶכְרֵחִי.
- המבנה גדול (עשרות שדות, מערכים בפנים) → מצביע מקלט כדי למנוע עותקים יקרים.
- עקביות: אם לפחות בשיטה אחת בסוג יש מקלט מצביע, השתמש מקלט מצביע גם עבור האחרים. כנס חשוב מאוד עבור ממשקים (מודול 6).
- סוגי "ערך" קטנים, בלתי ניתנים לשינוי (זמן.זמן, מספרים מרוכבים, קטנים מבנים) → מקבל ערך, קריא יותר.
שיטות על טיפוסים שאינם מבנה
אתה יכול להגדיר שיטות על כל סוג NAMED המוצהר בחבילה שלך:
type Celsius float64
func (c Celsius) ToFahrenheit() float64 {
return float64(c)*9/5 + 32
}
t := Celsius(20)
fmt.Println(t.ToFahrenheit()) // 68אינך יכול להגדיר אותם על סוגים מחבילות אחרות (למשל int, string): עליך
תחילה צור סוג מקומי בשם.
נסה את זה
הוסף שיטת מחרוזת Greet() (מקלט ערך) לאדם שמחזירה 'ciao <Name>'.
הצג רמז
מקלט בסוגריים לפני שם השיטה.
הפתרון זמין לאחר 3 ניסיונות
הוסף שיטת Rename(n string) עם מקלט POINTER שמשנה את p.Name.
הצג רמז
מקלט מצביע: `(p *אדם)`.
הפתרון זמין לאחר 3 ניסיונות
מתי כדאי להשתמש במקלט מצביע (p *T)?
func (t ?T) M() { ... }לְסַכֵּם
- שיטה = פונקציה עם מקלט:
func (r T) Name(...) ... { ... }. - מקבל ערך: פועל על עותק; מקלט מצביע: פועל על המקור.
- Go מבצעת את ההמרה
T↔*Tבאופן אוטומטי באתר השיחה. - מקלט מצביע כאשר: מוטציה + מבנה גדול + עקביות עם שיטות אחרות מהסוג.
- לעולם אל תערבב מקלטי ערך ומצביע על אותו סוג.
- השיטות עוברות על סוגי NAMED בחבילה הנוכחית (כולל non-struct).