Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meaning of ...interface{} (dot dot dot interface)

Tags:

go

Below is a piece of Go code I have question about. Specifically, what is a in this function?

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

Could anyone tell me what the three dots are here? And what does ...interface{} do?

like image 769
BufBills Avatar asked May 15 '14 05:05

BufBills


2 Answers

A parameter type prefixed with three dots (...) is called a variadic parameter. That means you can pass any number or arguments into that parameter (just like with fmt.Printf()). The function will receive the list of arguments for the parameter as a slice of the type declared for the parameter ([]interface{} in your case). The Go Specification states:

The final parameter in a function signature may have a type prefixed with .... A function with such a parameter is called variadic and may be invoked with zero or more arguments for that parameter.

A parameter:

a ...interface{}

Is, for the function equivalent to:

a []interface{}

The difference is how you pass the arguments to such a function. It is done either by giving each element of the slice separately, or as a single slice, in which case you will have to suffix the slice-value with the three dots. The following examples will result in the same call:

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

Will do the same as:

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

This is explained quite well in the Go Specification as well:

Given the function and calls

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

within Greeting, who will have the value nil in the first call, and []string{"Joe", "Anna", "Eileen"} in the second.

If the final argument is assignable to a slice type []T, it may be passed unchanged as the value for a ...T parameter if the argument is followed by .... In this case no new slice is created.

Given the slice s and call

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

within Greeting, who will have the same value as s with the same underlying array.

like image 128
ANisus Avatar answered Nov 16 '22 20:11

ANisus


As far as the interface{} term, it is the empty interface. In other words, the interface implemented by all variables in Go.

This is sort of analogous to java.lang.Object or System.Object in C#, but is instead inclusive of every variable type in the language. So it lets you pass in anything to the method.

like image 27
Dranyar Avatar answered Nov 16 '22 21:11

Dranyar