Um tipo de parâmetro prefixado com três pontos (...) é chamado de parâmetro variável . Isso significa que você pode passar qualquer número ou argumento para esse parâmetro (assim como com fmt.Printf()). A função receberá a lista de argumentos para o parâmetro como uma fatia do tipo declarado para o parâmetro ( []interface{}no seu caso). A especificação Go afirma:
O parâmetro final em uma assinatura de função pode ter um tipo prefixado com .... Uma função com tal parâmetro é chamada de variadic e pode ser chamada com zero ou mais argumentos para aquele parâmetro.
Um parâmetro:
a ...interface{}
É, para a função equivalente a:
a []interface{}
A diferença é como você passa os argumentos para tal função. Isso é feito fornecendo cada elemento da fatia separadamente ou como uma única fatia, caso em que você terá que sufocar o valor da fatia com os três pontos. Os exemplos a seguir resultarão na mesma chamada:
fmt.Println("First", "Second", "Third")
Fará o mesmo que:
s := []interface{}{"First", "Second", "Third"}
fmt.Println(s...)
Isso também é explicado muito bem na Especificação Go :
Dada a função e chamadas
func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
dentro Greeting, whoterá o valor nilna primeira chamada e []string{"Joe", "Anna", "Eileen"}na segunda.
Se o argumento final []Tpuder ser atribuído a um tipo de fatia , ele pode ser passado inalterado como o valor de um ...Tparâmetro se o argumento for seguido por .... Nesse caso, nenhuma nova fatia é criada.
Dado o slice se call
s := []string{"James", "Jasmine"}
Greeting("goodbye:", s...)
dentro Greeting, whoterá o mesmo valor sda mesma matriz subjacente.