שיעורי מודול (4/5)
סגירות ומתפקדות כערכים
ב-Go, פונקציות הן ערכים ממדרגה ראשונה: ניתן להקצות אותן משתנים, הועברו לפונקציות אחרות והוחזרו. סגירה היא א פונקציה מילולית (אנונימית) שלוכדת את המשתנים של ה- הסביבה שבה הוא מוגדר.
פונקציה מילולית
פונקציה ללא שם, כתובה בשורה. אתה קורא לזה מיד או להקצות את זה:
greet := func(name string) {
fmt.Println("ciao", name)
}
greet("Anna")
// invocata immediatamente:
func() { fmt.Println("subito") }()הסוג של greet הוא func(string).
לכידת הסביבה: סגירה
הפונקציה ליטרלית יכולה לקרוא ולשנות את המשתנים הנראים ב ההיקף המילוני שלו, גם לאחר שהפונקציה החיצונית חזרה:
func counter() func() int {
n := 0
return func() int {
n++
return n
}
}
c := counter()
fmt.Println(c(), c(), c()) // 1 2 3n "חי" כל עוד סגירה אחת לפחות מתייחסת אליו. כל קריאה ל
counter() יוצר n חדש ועצמאי.
סגירה כהתקשרות חוזרת
דפוס נפוץ מאוד:
nums := []int{3, 1, 2}
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})הסגירה לוכדת nums ומגדירה את ההזמנה.
מתפקד כפרמטרים
כדי לקבל פונקציה כפרמטר, כתוב את הסוג שלה:
func apply(nums []int, f func(int) int) []int {
out := make([]int, len(nums))
for i, n := range nums {
out[i] = f(n)
}
return out
}
double := func(x int) int { return x * 2 }
apply([]int{1, 2, 3}, double) // [2 4 6]אם החתימה הופכת קשה לקריאה, הגדר כינוי סוג:
type Transform func(int) int
func apply(nums []int, f Transform) []int { ... }נסה את זה
הגדר מונה() שמחזיר סגירה: כל קריאה לסגירה מגדילה ומחזירה מונה פנימי.
הצג רמז
יש להצהיר על 'n' לפני ההחזרה; הסגירה לוכדת את זה.
הפתרון זמין לאחר 3 ניסיונות
הקצה ל-f פונקציה מילולית שמדפיסה 'ciao', ואז קרא לה.
הצג רמז
תחביר: `f := func() { ... }` ואז `f()`.
הפתרון זמין לאחר 3 ניסיונות
מה זה מדפיס? (תיזהר מהיקף הסגירה)
mk := func() func() int {
x := 0
return func() int { x++; return x }
}
a := mk()
b := mk()
fmt.Println(a(), a(), b())לְסַכֵּם
- הפונקציות הן מהשורה הראשונה: ניתנות להקצאה, ניתנות לביצוע, ניתנות להחזרה.
- פונקציה מילולית:
func(params) ret { ... }, אנונימית. - סגירה: לוכדת את המשתנים של ההיקף המילוני, שומרת אותם בחיים.
- סוג פונקציה מפורש בפרמטרים:
func(int) int. - מאז Go 1.22, לכל for iteration יש עותק משלו של משתנה הלולאה.