Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 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 с тем же базовым массивом.

Ответ 2

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

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