Go в примери: Затваряния

Go поддържа безименни функции1, които могат да създават затваряния2.

Безименните функции са полезни, когато искате да създадете функция „посред“3 написаното, без да е нужно да я именувате.


  1. annonimous function – безименна функция. https://bg.wikipedia.org/wiki/Анонимна_функция
  2. closure – затваряне. https://bg.wikipedia.org/wiki/Затваряне_(информатика)
  3. inline – насред, посред, в реда на…
package main
import "fmt"

Функцията intSeq връща друга функция, която създаваме без име в тялото на intSeq. Върната функция затваря в себе си променливата i и така създава затвор за i.

func intSeq() func() int {
    i := 0
    return func() int {
        i++
        return i
    }
}
func main() {

Извикваме intSeq, като присвояваме изхода ѝ (функция) на променливата nextInt. Тази стойност-функция прихваща своя собствена стойност на i, която стойност се променя при всяко извикване на nextInt.

    nextInt := intSeq()

Вижте действието на затварянето от извикването на nextInt няколко пъти.

    fmt.Println(nextInt())
    fmt.Println(nextInt())
    fmt.Println(nextInt())

За да потвърдим, че състоянието на i е собственост на новопроизведената функция, създайте и извикайте нова.

    newInts := intSeq()
    fmt.Println(newInts())
}
$ go run closures.go
1
2
3
1

Последното свойство, което ще разгледаме засега е самоизвикването1.


  1. recursion – прибягване, а по-точно в случая – самоизвикване

Следващ пример: .