funcții variadice (…) în Go

Funcții care primesc oricâte argumente de același tip prin ...T; în funcție ele sunt un slice.

Sintaxă
func suma(numere ...int) int { ... }

suma(1, 2, 3)
suma(lista...)   // un slice trimis ca argumente separate

Ce face funcții variadice (...)

Dacă ultimul parametru al unei funcții are tipul ...T, funcția acceptă oricâte valori de tip T pe acea poziție, inclusiv niciuna. În interiorul funcției, parametrul este un slice []T. Exemple cunoscute: fmt.Println(a ...any), append(s, elemente...), min și max.

Dacă ai deja valorile într-un slice, îl trimiți cu ... după nume: suma(note...). În acest caz funcția primește chiar slice-ul tău (nu o copie), deci modificările făcute în funcție se văd afară. Doar ultimul parametru poate fi variadic.

Exemple

Exemplul 1: Suma unui număr oarecare de valori

package main

import "fmt"

func suma(numere ...int) int {
    total := 0
    for _, n := range numere {
        total += n
    }
    return total
}

func main() {
    fmt.Println(suma())
    fmt.Println(suma(5))
    fmt.Println(suma(10, 20, 30))
    note := []int{9, 8, 10}
    fmt.Println(suma(note...))
}

Rezultat

0
5
60
27

Exemplul 2: Parametri obișnuiți înaintea celui variadic

package main

import (
    "fmt"
    "strings"
)

func jurnal(nivel string, mesaje ...string) {
    fmt.Printf("[%s] număr de mesaje: %d | %s\n", nivel, len(mesaje), strings.Join(mesaje, "; "))
}

func main() {
    jurnal("INFO", "server pornit", "port 8080")
    jurnal("EROARE", "conexiune pierdută")
    jurnal("DEBUG")
}

Rezultat

[INFO] număr de mesaje: 2 | server pornit; port 8080
[EROARE] număr de mesaje: 1 | conexiune pierdută
[DEBUG] număr de mesaje: 0 |

Exemplul 3: Trimiterea mai departe a argumentelor any

args... transmite argumentele mai departe, nu un singur slice.

package main

import "fmt"

func afiseaza(prefix string, args ...any) {
    fmt.Print(prefix + " ")
    fmt.Println(args...)
}

func main() {
    afiseaza("comanda:", "pizza", 2, 45.5, true)
}

Rezultat

comanda: pizza 2 45.5 true

Greșeli frecvente

  • suma(note) în loc de suma(note...): cannot use note (variable of type []int) as int value in argument to suma.
  • Parametru variadic care nu este ultimul: can only use ... with final parameter.
  • Amestecarea valorilor separate cu un slice: suma(1, note...) dă too many arguments in call to suma.

Comenzi înrudite

  • func: Declară o funcție: parametri cu tip după nume, unul sau mai multe rezultate, metode și funcții anonime.
  • append: Adaugă elemente la finalul unui slice și returnează slice-ul rezultat, mărind memoria când e nevoie.
  • slice-uri: Lista dinamică din Go: o fereastră peste un array, cu lungime (len) și capacitate (cap), care crește cu append.
  • min și max: Returnează cel mai mic, respectiv cel mai mare dintre argumente; merg pe numere și texte (Go 1.21).