Znaczenie… interfejsu {} (interfejs z kropką i kropką)

93

Poniżej znajduje się fragment kodu Go, o który mam pytanie. A konkretnie, co jest aw tej funkcji?

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

Czy ktoś mógłby mi powiedzieć, jakie są tutaj trzy kropki? A co robi ...interface{}?

BufBills
źródło
33
Dotdotdot nazywa się wielokropek.
Erikw

Odpowiedzi:

161

Typ parametru poprzedzony trzema kropkami (...) nazywany jest parametrem wariadycznym . Oznacza to, że możesz przekazać dowolną liczbę lub argumenty do tego parametru (tak jak w przypadku fmt.Printf()). Funkcja otrzyma listę argumentów dla parametru jako wycinek typu zadeklarowanego dla parametru ( []interface{}w twoim przypadku). The Go Specyfikacja stanowi:

Ostatni parametr w sygnaturze funkcji może mieć typ poprzedzony znakiem .... Funkcja z takim parametrem nazywana jest wariadyczną i może być wywoływana z zerową lub większą liczbą argumentów dla tego parametru.

Parametr:

a ...interface{}

Czy dla funkcji równoważnej:

a []interface{}

Różnica polega na sposobie przekazywania argumentów do takiej funkcji. Odbywa się to przez podanie każdego elementu wycinka osobno lub jako pojedynczy wycinek, w którym to przypadku będziesz musiał dodać przyrostek wartości wycinka trzema kropkami. Poniższe przykłady spowodują to samo wywołanie:

fmt.Println("First", "Second", "Third")

Zrobi to samo, co:

s := []interface{}{"First", "Second", "Third"}
fmt.Println(s...)

Jest to całkiem dobrze wyjaśnione w specyfikacji Go :

Biorąc pod uwagę funkcję i wywołania

   func Greeting(prefix string, who ...string)
   Greeting("nobody")
   Greeting("hello:", "Joe", "Anna", "Eileen")

wewnątrz Greeting, whobędzie mieć wartość nilw pierwszym wywołaniu i []string{"Joe", "Anna", "Eileen"}w drugim.

Jeśli ostatni argument można przypisać do typu wycinka []T, może zostać przekazany niezmieniony jako wartość ...Tparametru, jeśli po argumencie następuje .... W tym przypadku nie jest tworzony nowy wycinek.

Biorąc pod uwagę kawałek si zadzwoń

   s := []string{"James", "Jasmine"}
   Greeting("goodbye:", s...)

wewnątrz Greeting, whobędą miały taką samą wartość, jak sz tego samego podstawowego tablicy.

ANisus
źródło
10

Jeśli chodzi o interface{}termin, jest to pusty interfejs. Innymi słowy, interfejs implementowany przez wszystkie zmienne w Go.

Jest to trochę analogiczne do java.lang.Objectlub System.Objectw C #, ale zamiast tego obejmuje każdy typ zmiennej w języku. Pozwala więc przekazać do metody wszystko.

Dranyar
źródło