Significado de ... interfaz {} (interfaz punto punto punto)


93

A continuación se muestra un fragmento del código Go sobre el que tengo preguntas. Específicamente, ¿qué hay aen esta función?

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

¿Alguien podría decirme qué son los tres puntos aquí? Y lo que ...interface{}hacer?


33
El dotdotdot se llama elipsis.
Erikw

Respuestas:


161

Un tipo de parámetro con el prefijo de tres puntos (...) se denomina parámetro variádico . Eso significa que puede pasar cualquier número o argumentos a ese parámetro (al igual que con fmt.Printf()). La función recibirá la lista de argumentos para el parámetro como una porción del tipo declarado para el parámetro ( []interface{}en su caso). La especificación Go establece:

El parámetro final en la firma de una función puede tener un tipo con el prefijo .... Una función con dicho parámetro se llama variadic y puede invocarse con cero o más argumentos para ese parámetro.

Un parámetro:

a ...interface{}

Es, para la función equivalente a:

a []interface{}

La diferencia es cómo se pasan los argumentos a dicha función. Se hace dando cada elemento de la rebanada por separado, o como una sola rebanada, en cuyo caso tendrá que agregar el sufijo al valor de la rebanada con los tres puntos. Los siguientes ejemplos resultarán en la misma llamada:

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

Hará lo mismo que:

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

Esto se explica bastante bien en la especificación Go :

Dada la función y las llamadas

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

dentro Greeting, whotendrá el valornil en la primera llamada y []string{"Joe", "Anna", "Eileen"}en la segunda.

Si el argumento final se puede asignar a un tipo de segmento []T, se puede pasar sin cambios como el valor de un...T parámetro si el argumento va seguido de .... En este caso, no se crea ningún segmento nuevo.

Dado el corte sy la llamada

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

inside Greeting, whotendrá el mismo valor que scon la misma matriz subyacente.


10

En cuanto al interface{}término, es la interfaz vacía. En otras palabras, la interfaz implementada por todas las variables en Go.

Esto es algo análogo a java.lang.Objecto System.Objecten C #, pero en cambio incluye todos los tipos de variable en el lenguaje. Entonces te permite pasar cualquier cosa al método.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.