En la parte 1 aprendimos el manejo básico de funciones en go, en este capitulo vamos a tratar funciones de una manera mas avanzada. Empecemos y manos a la obra:
Direcciones como parámetros en una Función
Pasar las direcciones de una variable a una función y modificar sus valores dentro de la función es sencillo, lo único que tenemos que hacer es desreferenciarlas.
package main import "fmt" //utilizando * indicamos que esperamos una dirección de entero y string func actualizar(x *int, y *string) { *x = *x + 5 // con * desreferenciamos la dirección de x y asignamos el valor *y = *y + " kylian" // desreferenciamos la dirección de x return } func main() { var goles = 20 var nombre= "mbape" fmt.Println("Antes de actualizar:", nombre, goles) //utilizando & indicamos que estamos enviando una dirección actualizar(&goles, &nombre) //imprimimos el valor de las variables fmt.Println("Despues de actualizar :", nombre, goles) }
Funciones Anónimas
Una función anónima es una función que fue declarada sin asignarle un nombre que la identifique, sin embargo las funciones anónimas pueden aceptar parámetros de entrada y regresar valores de salida , como lo hace una función estándar.
Veamos como asignar una función anónima a una variable.
package main import "fmt" var ( //asignamos la función anónima a la variable global triangulo areaTriangulo = func(b int, h int) int { return (b * h) / 2 } ) func main() { //imprimimos la variable global triangulo fmt.Println(areaTriangulo (30, 20)) }
Podemos hacerlo de la misma manera pero sin asignar la función a una variable y asignarle parámetros.
package main import "fmt" func main() { func(b int, h int) { fmt.Println((b * h) / 2) }(30, 20) }
Funciones de Cierre (Closures)
Estas funciones son un tipo de funciones anónimas, que tienen la capacidad de acceder a las variables definidas fuera del cuerpo de la función.
package main import "fmt" func main() { b := 30 h := 20 func() { var areaTriangulo int //tenemos la capacidad de acceder a las variables b y h areaTriangulo = b * h fmt.Println(areaTriangulo) }() }
Funciones de orden superior
Una función de orden superior, es una función que recibe una función como argumento o que retorna una función como salida. La funciones de orden superior operan sobre otras funciones, ya sea tomándolas como parámetros o devolviéndolas.
package main import "fmt" func suma(x, y int) int { return x + y } //la funcion suma parcial retorna una funcion llamada que toma dos argumentos func sumaParcial(x int) func(int) int { //funcion retornada en la primer funcion return func(y int) int { //ejecuta la funcion de menor orden return suma((x + 2), y) } } func main() { //asignamos la función de orden superior a la variable parcial parcial := sumaParcial(3) //ejecutamos la función anónima contenida dentro de la función superior fmt.Println(parcial(7)) }
En el ejemplo anterior devolvimos una función y un entero en la función superior, ahora veamos como devolver dos funciones y un valor entero.
package main import "fmt" //Retorna dos funciones y un entero func sumaDeCuadrados(x int) func(int) func(int) int { //retorna una funcion y un entero return func(y int) func(int) int { //retorna el entero return func(z int) int { return x*x + y*y + z*z } } } func main() { // el resultado de la función será 2*2 + 3*3 + 4*4 fmt.Println(sumaDeCuadrados(2)(3)(4)) }
Tipos de Funciones definidas por el usuario
Go soporta definir nuestros propios tipos de funciones, con esto podemos asignarle un nombre a cada función y tener de una manera más limpia nuestras funciones de orden superior, veamos el mismo ejemplo anterior pero con funciones de tipo definidas.
package main import "fmt" //definimos el tipo Primera como una función //que espera un int y retorna un int type Primera func(int) int //definimos el tipo segunda como una función //que espera un int y retorna un tipo Primera type Segunda func(int) Primera func sumaDeCuadrados(x int) Segunda { return func(y int) Primera { return func(z int) int { return x*x + y*y + z*z } } } func main() { // 2*2 + 3*3 + 4*4 fmt.Println(sumaDeCuadrados(2)(3)(4)) }