Ответ 1
Тип параметра с префиксом из трех точек (...) называется переменным параметром. Это означает, что вы можете передать любое число или аргументы в этот параметр (как в fmt.Printf()
). Функция получит список аргументов для параметра в виде фрагмента типа, объявленного для параметра ([]interface{}
в вашем случае). В спецификации Go указано:
Последний параметр в сигнатуре функции может иметь тип с префиксом.... Функция с таким параметром называется variadic и может вызываться с нулевым или большим количеством аргументов для этого параметра.
Параметр:
a ...interface{}
Есть, для функции эквивалентно:
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
с тем же базовым массивом.