func în Go

Declară o funcție: parametri cu tip după nume, unul sau mai multe rezultate, metode și funcții anonime.

Sintaxă
func nume(a int, b string) (int, error) {
    ...
}

func (r Receptor) Metoda() { ... }   // metodă
f := func(x int) int { return x * 2 } // funcție anonimă

Ce face func

func declară o funcție. Tipul se scrie după numele parametrului (a int), iar parametrii consecutivi de același tip se pot grupa: func aria(lungime, latime float64) float64. Tipul rezultatului vine după paranteze.

O funcție Go poate returna mai multe valori: (int, error). Așa se raportează erorile: ultima valoare returnată este un error, care este nil când totul a mers bine. Rezultatele pot avea și nume ((suma int, err error)); ele pornesc de la valoarea zero și se returnează cu un simplu return.

Funcțiile sunt valori: le poți pune în variabile, le poți trimite ca argumente și le poți returna. O funcție fără nume (func(x int) int { ... }) este o funcție anonimă, iar dacă folosește variabile din jur devine closure. Cu un receptor înaintea numelui (func (c Cont) Sold()) funcția devine metodă.

Parametri

Parametru Descriere
parametri Listă nume tip, separate prin virgulă. Toți parametrii se transmit prin copiere (pentru a modifica originalul trimiți un pointer).
rezultate Niciunul, un tip (int) sau mai multe între paranteze ((int, error)), eventual cu nume.

Ce returnează

Ce declară funcția după paranteze; valorile se trimit cu return.

Exemple

Exemplul 1: Funcție cu mai multe rezultate

Ultimul rezultat este eroarea; apelantul o verifică imediat.

package main

import (
    "errors"
    "fmt"
)

func imparte(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("împărțire la zero")
    }
    return a / b, nil
}

func main() {
    if r, err := imparte(100, 8); err == nil {
        fmt.Println("100 / 8 =", r)
    }
    if _, err := imparte(5, 0); err != nil {
        fmt.Println("eroare:", err)
    }
}

Rezultat

100 / 8 = 12.5
eroare: împărțire la zero

Exemplul 2: Rezultate cu nume

minim și maxim sunt variabile ale funcției; return simplu le trimite.

package main

import "fmt"

func extreme(note []int) (minim, maxim int) {
    minim, maxim = note[0], note[0]
    for _, n := range note[1:] {
        if n < minim {
            minim = n
        }
        if n > maxim {
            maxim = n
        }
    }
    return
}

func main() {
    mic, mare := extreme([]int{7, 10, 5, 9})
    fmt.Println("cea mai mică notă:", mic, "cea mai mare:", mare)
}

Rezultat

cea mai mică notă: 5 cea mai mare: 10

Exemplul 3: Funcții ca valori

aplica primește o funcție ca parametru; îi trimitem una anonimă.

package main

import "fmt"

func aplica(preturi []float64, f func(float64) float64) []float64 {
    rezultat := make([]float64, len(preturi))
    for i, p := range preturi {
        rezultat[i] = f(p)
    }
    return rezultat
}

func main() {
    preturi := []float64{100, 250, 40}
    cuTVA := aplica(preturi, func(p float64) float64 { return p * 1.21 })
    reducere := aplica(preturi, func(p float64) float64 { return p * 0.9 })
    fmt.Println("cu TVA 21%:", cuTVA)
    fmt.Println("cu 10% reducere:", reducere)
}

Rezultat

cu TVA 21%: [121 302.5 48.4]
cu 10% reducere: [90 225 36]

Greșeli frecvente

  • Tipul înaintea numelui (func f(int a)): în Go tipul vine după nume.
  • Ignorarea erorii returnate: r, _ := imparte(5, 0) ascunde problema. Verifică err.
  • Așteptarea ca funcția să modifice un struct trimis ca valoare: primește o copie. Trimite un pointer (*T).

Comenzi înrudite

  • return: Încheie funcția curentă și trimite apelantului valorile rezultat (zero, una sau mai multe).
  • closures (funcții anonime): Funcții anonime care „țin minte” variabilele din jurul lor și le pot citi și modifica după ce funcția exterioară s-a terminat.
  • funcții variadice (...): Funcții care primesc oricâte argumente de același tip prin …T; în funcție ele sunt un slice.
  • metode: Funcții legate de un tip prin receptor; cu receptor pointer pot modifica valoarea pe care sunt apelate.
  • defer: Amână un apel de funcție până la ieșirea din funcția curentă; folosit pentru închideri și curățenie.