sync.OnceFunc în Go

Returnează o funcție care rulează f doar la primul apel; apelurile următoare nu fac nimic.

Sintaxă
func OnceFunc(f func()) func()

Ce face sync.OnceFunc

sync.OnceFunc(f) este o formă mai comodă a lui sync.Once: primești direct o funcție pe care o poți apela de oriunde, de oricâte ori, din oricâte goroutine. f rulează o singură dată.

Diferența față de Once.Do: dacă f se oprește cu panică, funcția returnată repetă aceeași panică la fiecare apel, deci eroarea nu trece neobservată.

Parametri

Parametru Descriere
f Funcția care trebuie rulată o singură dată.

Ce returnează

O funcție func() sigură pentru apeluri concurente.

Exemple

Exemplul 1: Închidere apelată de mai multe ori

Conexiunea se închide o singură dată, deși inchide este apelat din trei locuri.

package main

import (
	"fmt"
	"sync"
)

func main() {
	inchide := sync.OnceFunc(func() {
		fmt.Println("Închid conexiunea la baza de date")
	})

	inchide()
	inchide()

	var wg sync.WaitGroup
	for range 5 {
		wg.Go(inchide)
	}
	wg.Wait()
	fmt.Println("Gata")
}

Rezultat

Închid conexiunea la baza de date
Gata

Exemplul 2: Mesaj de avertizare afișat o dată

package main

import (
	"fmt"
	"sync"
)

var avertizare = sync.OnceFunc(func() {
	fmt.Println("Atenție: funcția CalculVechi este învechită, folosește Calcul")
})

func CalculVechi(a, b int) int {
	avertizare()
	return a + b
}

func main() {
	for i := 1; i <= 3; i++ {
		fmt.Println("Rezultat:", CalculVechi(i, 10))
	}
}

Rezultat

Atenție: funcția CalculVechi este învechită, folosește Calcul
Rezultat: 11
Rezultat: 12
Rezultat: 13

Greșeli frecvente

  • Apelezi sync.OnceFunc(f) de fiecare dată când ai nevoie (în buclă sau în funcție). Fiecare apel creează o funcție nouă, cu „o dată” al ei; creează-o o singură dată și păstreaz-o.

Comenzi înrudite

  • sync.Once: Garantează că o funcție rulează o singură dată, chiar dacă Do este apelat de multe goroutine (inițializare leneșă).
  • sync.OnceValue: Returnează o funcție care calculează valoarea o singură dată și o dă înapoi la fiecare apel; OnceValues pentru două valori.