lunes, 29 de octubre de 2018

Funciones en Go

Hay un viejo dicho de programadores (que, a su vez fue promulgado por antiguos generales en la guerra) que dice: "Divide y vencerás".


Cuando un programa se hace más grande y complejo, será necesario organizar mejor el código, identificando qué partes de dicho código se pueden reutilizar. Después se definen y escriben funciones con dicho código.

Funciones simples

En el siguiente ejemplo vamos a ilustrar una función muy simple:

package main

import "fmt"

func main() {
   saludo()
}

// Funcion simple sin parametros
func saludo() {
   fmt.Println("Hola")
}

Toda función se define a través de la palabra clave func. A continuación, se define el nombre de la función, seguido de unos paréntesis. Después, se abre un bloque delimitado por "llaves" ({ y }), el cual contendrá el código de la función.

En Go, la ejecución de todo programa comienza con la función main() (del inglés "principal").

En el programa anterior hemos definido y creado una función llamada saludo(), la cual visualiza en pantalla el texto "Hola".

Para invocar o llamar a esta función, simplemente hay que escribir el nombre de la función, como si se tratase de una sentencia o comando.

Nota: A veces, las funciones se denominan métodos. Esto es común en otros lenguajes de programación. Una forma de diferenciar ambos conceptos, es que un método no retorna ningún valor, mientras que una función sí que retorna valores. En el ejemplo, saludo() es, en un contexto purista, un método. Sin embargo, en Go, nos referiremos siempre con el término función (de hecho, la palabra clave func se utiliza tanto para funciones como para métodos).

Parámetros en la función

Una de las ventajas de usar funciones es que podemos reutilizar código que pueda hacer distintas cosas, dependiendo de unos valores o parámetros.

Un parámetro es una variable que capturará un valor de entrada, el cual utilizará el código de la función. El parámetro se define dentro de los paréntesis de la definición de la función, y se pueden definir tantos parámetros como necesitemos.

Vamos a modificar nuestra función saludo para que nos salude con el nombre y los apellidos que deseemos.

package main

import "fmt"

func main() {
   saludar("Rafael", "Hernampérez")
   saludar("Eduardo", "Fernández")
}

// Funcion con parametros
func saludar(nombre, apellidos string) {
   fmt.Printf("Hola, %v %v\n", nombre, apellidos)
}

El primer cambio ha sido cambiar el nombre de la función por saludar(). Es simplemente una convención, ya que es mejor nombrar las funciones con un verbo, ya que realizan una acción. Además, un nombre en forma verbal nos va a indicar rápidamente que es una función, y la distinguiremos rápidamente de una variable, que suele ser un sustantivo o un nominativo.

En la definición de la función, definimos los parámetros entre los paréntesis, mediante el nombre de cada parámetro y su tipo. Internamente, el parámetro será una variable de la función, la cual recogerá los valores que se pasen en la invocación. Los valores se irán asignando en el mismo orden, de izquierda a derecha, a cada uno de los parámetros de la función.

Retorno de valores

Otra de las grandes ventajas de una función es la posibilidad de retornar valores. Esto es especialmente útil a la hora de procesar ciertos valores de entrada para obtener un valor procesado o calculado.

En la definición de la función, tras los paréntesis, se indica el tipo de valor que va a retornar la función.

Dentro de la función, retornaremos el valor procesado mediante la palabra clave return. El valor a retornar debe coincidir con el tipo declarado anteriormente.

En el siguiente ejemplo definimos la función sumar(), la cual tomará dos valores de entrada (a y b) de tipo int. Sumará el valor de estos dos valores y retornará el resultado.

package main

import "fmt"

func main() {
   var sum1, sum2 int = 13, 5
   var resultado int = sumar(sum1, sum2)
   fmt.Printf("%v + %v = %v\n", sum1, sum2, resultado)
}

// Funcion con retorno
func sumar(a, b int) int {
   return a + b
}

Al retornar un valor, éste será devuelto a la llamada a la función, por lo que debemos capturar dicho resultado. En el caso anterior, se ha asignado a la variable resultado, pero también se podría haber capturado mediante alguna sintaxis que utilice el valor devuelto. En el siguiente ejemplo, el valor devuelto es esperado dentro de Printf, quien visualizará en pantalla dicho valor.

func main() {
   var sum1, sum2 int = 13, 5
   fmt.Printf("%v + %v = %v\n", sum1, sum2, sumar(sum1, sum2))
}

Retorno de múltiples valores

En Go podemos definir funciones que retorne más de un valor. Para ello, tras los paréntesis del nombre de la función, se escribirán los diferentes tipos de los valores a retornar, escritos también entre paréntesis.

package main

import "fmt"

func main() {
   latitud, longitud := getCoordenadas()
   fmt.Printf("Latitud: %v / Longitud: %v\n", latitud, longitud)
}

// Funcion con retorno de varios valores
func getCoordenadas() (float64, float64) {
   return 40.4242971, -3.7143414
}

Cuando se invoca a una función, se han de pasar los valores de entrada (parámetros) en el mismo orden y tipo en que está definida la función, de izquierda a derecha. De igual modo, cuando se retornan varios valores, también hay que capturar los valores de salida en el mismo orden y tipo en que se retornan.

Enlaces de interés

No hay comentarios:

Publicar un comentario