Salt la conținutul principal
Modulul 3 · Lecția 2 din 512/50 în curs~12 min
Lecții din modul (2/5)

Returnări multiple și returnări denumite

În Go, o funcție poate returna valori multiple. Este mecanismul care activează modelul (value, error) pe care l-ați văzut deja și care se răspândește întreaga bibliotecă standard.

Retururi multiple

Tipurile de returnare merg între paranteze, separate prin virgulă:

Go
func divmod(a, b int) (int, int) {
    return a / b, a % b
}

q, r := divmod(17, 5) // q=3, r=2

Sunt destructurate cu atribuții multiple. Pentru a arunca unul dintre valorile folosesc _:

Go
_, r := divmod(17, 5) // solo il resto

Modelul canonic (T, error)

Aproape toate stdlib-ul îl urmează. error este ÎNTOTDEAUNA ultimul:

Go
func read(path string) ([]byte, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("read %q: %w", path, err)
    }
    return data, nil
}

Returnări denumite

Puteți numi valorile returnate: acestea devin variabile predeclarate inițializate la zero și return fără argumente le returnează („naked return"):

Go
func divmod(a, b int) (q, r int) {
    q = a / b
    r = a % b
    return       // naked: ritorna q, r
}

Returnările denumite apar și în sfaturile instrumente ale documentației, așa că sunt utile ca o formă de documentație inline pentru funcții complexe — nu doar pentru întoarcerea goală.

Mai mult de două întoarceri?

Nimic nu te împiedică să (int, int, int, error), dar dacă simți nevoia este aproape întotdeauna un semn că ar trebui să returnați o struct:

Go
type Result struct {
    Sum  int
    Avg  float64
    Max  int
}

func analyze(nums []int) (Result, error) { ... }

Încearcă

Exercițiu#go.m3.l2.e1
Încercări: 0Se încarcă…

Definiți divmod(a, b int) (int, int) care returnează coeficientul și restul.

Se încarcă editorul...
Afișează indiciu

Tipuri returnate între paranteze: `(int, int)`.

Soluție disponibilă după 3 încercări

Exercițiu#go.m3.l2.e2
Încercări: 0Se încarcă…

Implementați safeDiv(a, b int) (int, error): if b == 0 return (0, errors.New('divisione per zero')), în caz contrar (a/b, nil).

Se încarcă editorul...
Afișează indiciu

Eroare ÎNTOTDEAUNA ca ultima valoare. La eroare: valoare zero + eroare.

Soluție disponibilă după 3 încercări

Quiz#go.m3.l2.e3
Gata

Ce imprimă acest program, folosind returnări denumite?

Go
func f() (a, b int) {
    a = 1
    b = 2
    return
}
x, y := f()
fmt.Println(x, y)
Opțiuni de răspuns

Recapitulare

  • Valori multiple între paranteze: func f() (T1, T2, error).
  • Convenție: error ÎNTOTDEAUNA ca ultima valoare; la eroare, valoare zero + eroare.
  • Returnările denumite predeclară variabilele și permit returnările simple.
  • Naked returnează doar în funcții foarte scurte; dincolo de asta, lizibilitatea are de suferit.
  • Mai mult de 2-3 retururi? Probabil vrei o structură.