ProgramaciónDesarrollador Backend

Describe cómo se implementan las funciones variádicas (funciones con un número variable de argumentos) en Go. ¿Cómo se deben declarar y llamar correctamente, y qué inconvenientes pueden surgir al pasar slices?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

Las funciones variádicas en Go permiten aceptar un número variable de argumentos de un mismo tipo gracias a la sintaxis con tres puntos .... Por ejemplo:

func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }

Se puede llamar a esta función con cualquier número de argumentos:

result := sum(1, 2, 3, 4) // 10

O pasar un slice utilizando la sintaxis ...:

numbers := []int{1,2,3} result := sum(numbers...) // 6

Particularidades:

  • Dentro de la función, los parámetros variádicos se ven como un slice ([]T). Esto significa que se puede pasar un slice ya preparado.
  • Estos parámetros siempre deben ser los últimos en la lista de parámetros de la función.
  • Si se pasa un slice sin ..., la función espera un parámetro normal de tipo []T, no un variádico.

Pregunta trampa

¿Qué resultado dará el siguiente código y por qué?

func printInts(nums ...int) { fmt.Printf("%#v ", nums) } ints := []int{1, 2, 3} printInts(ints)

Muchos erróneamente creen que este código se compilará, pero en realidad dará un error de compilación:

Error: no se puede pasar un slice sin ... a un parámetro variádico.

Correcto:

printInts(ints...) // OK

Ejemplos de errores reales debido al desconocimiento de las particularidades del tema


Historia

En un gran proyecto, la función de registro se describió como func Log(msgs ...string). Al pasar un slice de strings preparado previamente, llamaban simplemente Log(strings), obteniendo una salida de log incorrecta o panic durante la ejecución. La razón: falta de ..., por lo que la función percibía un único argumento de tipo []string, en lugar de strings separadas.


Historia

En una de las funciones utilitarias, se requería procesar parámetros, entre los cuales había un slice, y agregarle más elementos dentro. Se esperaba que ... creara una copia del slice, en lugar de pasar una referencia, pero dentro de la función se modificaba el slice, lo que afectaba inesperadamente a la parte que lo llamaba, especialmente si el slice original era un buffer reutilizable.


Historia

Un desarrollador implementó funciones de agregación utilizando un parámetro variádico, pero uno de sus colegas utilizó incorrectamente la sintaxis de llamada a través de un casting: sum(interface{}([]int)), lo que llevaba a errores implícitos en tiempo de ejecución, mientras que lo correcto sería usar explícitamente sum(slice...). El desconocimiento de los matices causaba errores no evidentes durante las refactorizaciones masivas.