Перейти к основному содержимому
Модуль 3 · Урок 3 из 513/50 в курсе~10 min
Уроки модуля (3/5)

Вариадические функции

Вариадические функции принимают произвольное количество аргументов того же типа. Вы объявляете их, помещая ... перед типом последнего параметр. Внутри функции параметром является срез.

Декларация

Go
func sum(nums ...int) int {
    tot := 0
    for _, n := range nums {
        tot += n
    }
    return tot
}

sum()              // 0   (nums = []int{})
sum(1)             // 1
sum(1, 2, 3, 4)    // 10

Только параметр last может быть переменным:

Go
func log(prefix string, values ...any) { ... }   // ok
// func wrong(...int, suffix string) {}            // ERRORE

Распространение кусочка

Если у вас уже есть срез, вы можете передать его переменной функции с помощью ...:

Go
nums := []int{1, 2, 3}
sum(nums...)         // 6 — espande lo slice nei singoli argomenti

"..." идет после фрагмента. Без распространения вы получите тип ошибка: вы должны передать []int, где функция ожидает последовательность из int.

nums — это фрагмент, а не новый контейнер.

Внутри функция nums имеет тип []int. Все стандартные кусочки работают операции: len(nums), nums[0], range и т. д.

Классический вариант использования: fmt.Println

Все функции Print* fmt являются вариативными:

Go
// signature (semplificata):
// func Println(a ...any) (n int, err error)

fmt.Println("ciao", 42, true)
args := []any{"a", "b", "c"}
fmt.Println(args...)

Попробуйте это

Упражнение#go.m3.l3.e1
Попыток: 0Загрузка…

Определите sum(nums ...int) int, который возвращает сумму всех аргументов.

Загрузка редактора…
Показать подсказку

Внутри функция `nums` имеет тип `[]int`.

Решение доступно после 3 попыток

Упражнение#go.m3.l3.e2
Попыток: 0Загрузка…

Вызовите существующую функцию суммы, передав номера срезов с расширением `nums...`.

Загрузка редактора…
Показать подсказку

`...` идет ПОСЛЕ имени фрагмента.

Решение доступно после 3 попыток

Quiz#go.m3.l3.e3
Готово

Внутри `func f(args ...string)` какой тип `args`?

Go
func f(args ...string) {
    _ = args
}
Варианты ответа

Резюме

  • ...T в качестве ПОСЛЕДНЕГО параметра = вариативная функция; внутри это []T.
  • Вызывается с одиночными значениями: компилятор собирает их в срез.
  • Вызывается с существующим фрагментом: slice... (распространение, повторное использование фрагмента).
  • Все функции fmt.Print* являются вариативными.
  • Только последний параметр может быть переменным.