Тип параметра с префиксом из трех точек (...) называется параметром с переменным числом аргументов . Это означает, что вы можете передать в этот параметр любое число или аргументы (как и в случае с fmt.Printf()
). Функция получит список аргументов для параметра в виде фрагмента типа, объявленного для параметра ( []interface{}
в вашем случае). В спецификации Go говорится:
Последний параметр в сигнатуре функции может иметь тип с префиксом .... Функция с таким параметром называется вариативной и может быть вызвана с нулем или более аргументов для этого параметра.
Параметр:
a ...interface{}
Is для функции, эквивалентной:
a []interface{}
Разница в том, как вы передаете аргументы такой функции. Это делается либо путем предоставления каждого элемента среза отдельно, либо в виде одного среза, и в этом случае вам нужно будет добавить к значению среза три точки. Следующие примеры приведут к такому же вызову:
fmt.Println("First", "Second", "Third")
Будет делать то же самое, что и:
s := []interface{}{"First", "Second", "Third"}
fmt.Println(s...)
Это также довольно хорошо объясняется в спецификации Go :
Учитывая функцию и вызовы
func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
внутри Greeting
, who
будет иметь значение nil
в первом вызове, а []string{"Joe", "Anna", "Eileen"}
во втором.
Если последний аргумент присваивается типу среза []T
, он может быть передан без изменений как значение ...T
параметра, если за аргументом следует ...
. В этом случае новый срез не создается.
Учитывая кусочек s
и звонок
s := []string{"James", "Jasmine"}
Greeting("goodbye:", s...)
в пределах Greeting
, who
будет иметь то же значение, s
с тем же основным массивом.