Значение… interface {} (точка точка точка интерфейс)

93

Ниже приведен фрагмент кода Go, по которому у меня возник вопрос. Конкретно что aв этой функции?

func DPrintf(format string, a ...interface{}) (n int, err error) {
  if Debug > 0 {
    n, err = fmt.Printf(format, a...)
  }
  return
}

Может ли кто-нибудь сказать мне, что здесь за три точки? А что ...interface{}делать?

BufBills
источник
33
Точка называется многоточием.
Erikw

Ответы:

161

Тип параметра с префиксом из трех точек (...) называется параметром с переменным числом аргументов . Это означает, что вы можете передать в этот параметр любое число или аргументы (как и в случае с 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с тем же основным массивом.

Анисус
источник
10

Что касается interface{}термина, то это пустой интерфейс. Другими словами, интерфейс реализован всеми переменными в Go.

Это своего рода аналог java.lang.Objectили System.Objectв C #, но вместо этого включает все типы переменных в языке. Таким образом, он позволяет передавать в метод что угодно.

Драньяр
источник