
El equipo de Mail.ru Cloud Solutions hatraducido un artículo sobre funciones variadas en Go. Su autor explica en qué se diferencian las funciones variadas de las funciones ordinarias y cómo crearlas.
¿Qué es una función variádica?
Función: un fragmento de código diseñado para realizar una tarea específica. A la función se le pasan uno o más argumentos y devuelve uno o más resultados.
Las funciones variantes son las mismas que las funciones regulares, pero pueden tomar un número infinito o variable de argumentos.
func f(elem ...Type)
Esta es una sintaxis típica de función variádica. El operador
..., también conocido como operador de boxeo, le dice a Go que almacene todos los argumentos de tipo Typeen un parámetro elem. En otras palabras, Go crea una variable elemcon un tipo []Type, es decir, un segmento. Y todos los argumentos pasados a la función se almacenan en el segmento elem.
Veamos un ejemplo de función
append().
append([]Type, args, arg2, argsN)
La función
appendespera que el primer argumento sea un segmento de tipo Typeseguido de un número arbitrario de argumentos. Pero, ¿cómo se agrega una rebanada s2a una rebanada s1?
De la definición de la función,
append()se deduce que no podemos pasarle dos porciones; Typesolo hay un argumento de tipo . Por lo tanto, usamos el operador de unboxing ...para descomprimir el segmento en una serie de argumentos. Luego se pueden pasar a la función append.
append(s1, s2...)
...denota tanto el operador de embalaje como el operador de desembalaje. El operador de unboxing siempre aparece después del nombre de la variable.
En nuestro ejemplo, las rodajas
s1y s2el mismo tipo. Por lo general, conocemos los parámetros de una función y la cantidad de argumentos que toma. ¿Cómo sabe una función acceptcuántos parámetros se le han pasado?
Si observa la declaración de la función
append, puede ver la expresión elems ...Type. Empaqueta todos los argumentos, comenzando por el segundo, en un segmento elems.
func append(slice []Type, elems ...Type) []Type
Solo el último argumento en una declaración de función puede ser variable.
Por lo tanto, el primer argumento de la función
appendes solo un segmento, ya que se define como un segmento. Todos los argumentos posteriores se empaquetan en un argumento llamado elems.
Ahora veamos cómo crear su propia función variada.
Cómo crear una función variada
Como se mencionó anteriormente, una función variada es una función regular que toma un número variable de argumentos. Para hacer esto, necesita usar el operador de boxeo
...Type.
Escribamos una función
getMultiplescon un primer argumento de factortipo int(factor de multiplicación) y un número variable de argumentos de tipo adicionales int. Se empaquetarán en una rodaja args.
Úselo para
makecrear un sector vacío, tiene el mismo tamaño que el sector args. Usando un bucle for range, multiplique los elementos de corte argspor factor. Colocamos el resultado en un nuevo segmento vacío multiples, que devolveremos como resultado de la función.
func getMultiples(factor int, args ...int) []int {
multiples := make([]int, len(args))
for index, val := range args {
multiples[index] = val * factor
}
return multiples
}
Esta es una función muy simple, aplícala dentro de un bloque
main().
func main() {
s := []int{10, 20, 30}
mult1 := getMultiples(2, s...)
mult2 := getMultiples(3, 1, 2, 3, 4)
fmt.Println(mult1)
fmt.Println(mult2)
}
https://play.go.org/p/BgU6H9orhrn
¿Qué sucede si, en el ejemplo anterior, pasa un segmento a una función
getMultiplescomo segundo argumento? El compilador reportará un error: en el argumentogetMultiplesno se puede usars (type [] int)como tipoint. Esto se debe a que el segmento tiene un tipo del que[]int, getMultiplesespera parámetrosint.
Cómo se pasa un segmento a una función variada
Slice es una referencia a una matriz. Entonces, ¿qué sucede cuando pasa una porción a una función variada usando el operador de unboxing? ¿Go crea un nuevo segmento
argso utiliza un segmento antiguo s?
Como no tenemos herramientas de comparación
args == s, necesitamos cambiar el segmento args. Luego averiguamos si el corte original ha cambiado s.
https://play.go.org/p/fbNgVGu6JZO
En el ejemplo anterior, cambiamos ligeramente la función
getMultiples. Y en lugar de crear un nuevo corte, asignamos los resultados del cálculo a los elementos del corte args, reemplazando los elementos entrantes con los elementos multiplicados.
Como resultado, vemos que los valores del segmento original
shan cambiado. Si pasa argumentos a la función variadic a través del operador de unboxing, Go usa referencias a la matriz de datos subyacente al original para crear un nuevo segmento. Tenga cuidado de no cometer un error, de lo contrario, los datos originales cambiarán como resultado de los cálculos.
¡Buena suerte!
Qué más leer: