Una función es una sección de código que, una vez definida, se puede volver a utilizar. Las funciones se utilizan para facilitar más la comprensión de su código mediante su división en tareas pequeñas y comprensibles que se pueden utilizar más de una vez en su programa.
Go se entrega con una potente biblioteca estándar que cuenta con muchas funciones predefinidas. Las siguientes son algunas que probablemente ya conozca del paquete fmt:
fmt.Println()
, que imprime objetos en una salida estándar (en mayoría de los casos, su terminal).fmt.Printf()
, que le permite dar formato a su resultado impreso.Los nombres de las funciones incluyen paréntesis y pueden contener parámetros.
En este tutorial, repasaremos la forma de definir sus propias funciones para utilizarlas en sus proyectos de codificación.
Comencemos convirtiendo el clásico programa “Hello, World!” en una función.
Crearemos un nuevo archivo de texto en nuestro editor de texto preferido e invocaremos el programa hello.go
. A continuación, definiremos la función.
Las funciones se definen usando la palabra clave func
. Luego, se muestra un nombre que usted elige y un conjunto de paréntesis que contienen cualquier parámetro que la función tome (pueden estar vacíos). Las líneas de código de las funciones se escriben entre llaves {}
.
En este caso, definiremos una función llamada hello()
:
func hello() {}
Con esto, se establece la instrucción inicial para crear una función.
A partir de aquí, añadiremos una segunda línea para proporcionar las instrucciones de lo que hace la función. En este caso, imprimiremos Hello, World!
en la consola:
func hello() {
fmt.Println("Hello, World!")
}
Ahora, nuestra función está definida por completo, pero si ejecutamos el programa en este momento no ocurrirá nada porque no invocamos la función.
Por lo tanto, dentro de nuestro bloque main()
de la función, invocaremos la función con hello()
:
package main
import "fmt"
func main() {
hello()
}
func hello() {
fmt.Println("Hello, World!")
}
Ahora, ejecutaremos el programa:
- go run hello.go
Obtendrá el siguiente resultado:
OutputHello, World!
Observe que también implementamos una función llamada main()
. main()
es una función especial que indica al compilador que este es el punto en el que se debe** iniciar** el programa. Para cualquier programa que quiera que sea ejecutable (un programa que pueda ejecutarse desde la línea de comandos), necesitará una función main()
. La función main()
debe aparecer una sola vez, debe estar en el paquete main()
y no debe recibir ni mostrar argumentos. Esto permite la ejecución del programa en cualquier programa de Go. Como indica el siguiente ejemplo:
package main
import "fmt"
func main() {
fmt.Println("this is the main section of the program")
}
Las funciones pueden ser más complejas que la función hello()
que definimos. Entre otras opciones, podemos usar bucles for
e instrucciones condicionales dentro de nuestro bloque de función.
Por ejemplo, la siguiente función utiliza una instrucción condicional para verificar si la entrada de la variable name
contiene una vocal. Luego, emplea un bucle for
para la iteración sobre las letras de la cadena name
.
package main
import (
"fmt"
"strings"
)
func main() {
names()
}
func names() {
fmt.Println("Enter your name:")
var name string
fmt.Scanln(&name)
// Check whether name has a vowel
for _, v := range strings.ToLower(name) {
if v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u' {
fmt.Println("Your name contains a vowel.")
return
}
}
fmt.Println("Your name does not contain a vowel.")
}
La función name()
que definimos aquí configura una variable name
con entrada y, luego, establece una instrucción condicional dentro de un bucle for
. Esto indica cómo se puede organizar el código dentro de la definición de una función. Sin embargo, dependiendo de lo que pretendamos de nuestro programa y de la forma en que queramos configurar nuestro código, tal vez nos convenga definir la instrucción condicional y el bucle for
como dos funciones separadas.
La definición de funciones dentro de un programa hace que nuestro código sea modular y reutilizable para que podamos invocar a las mismas funciones sin tener que volver a escribirlas.
Hasta ahora, examinamos funciones con paréntesis vacíos que no toman argumentos, pero podemos definir parámetros en las definiciones de las funciones dentro de sus paréntesis.
Un parámetro es una entidad con nombre en la definición de una función que especifica un argumento que la función puede aceptar. En Go, debe especificar el tipo de datos para cada parámetro.
Vamos a crear un programa que repite una palabra una cantidad de veces especificada. Tomará un parámetro string
llamado word
y un parámetro int
llamado reps
que indicará la cantidad de veces que se debe repetir la palabra.
package main
import "fmt"
func main() {
repeat("Sammy", 5)
}
func repeat(word string, reps int) {
for i := 0; i < reps; i++ {
fmt.Print(word)
}
}
Establecimos el valor Sammy
para el parámetro word
y el valor 5
para el parámetro reps
. Estos valores corresponden a cada parámetro en el orden en el que se proporcionaron. La función repeat
tiene un bucle for
que se repetirá la cantidad de veces especificada en el parámetro reps
. En cada repetición, se imprime el valor del parámetro word
.
Este es el resultado del programa:
OutputSammySammySammySammySammy
Si tiene un conjunto de parámetros con el mismo valor, puede omitir la repetición de la especificación de tipo. Crearemos un pequeño programa que tenga en cuenta los parámetros x
, y
y z
, todos ellos valores int
. Crearemos una función que añada los parámetros juntos en diferentes configuraciones. La función imprimirá la suma de ellas. Luego, invocaremos la función y le pasaremos números.
package main
import "fmt"
func main() {
addNumbers(1, 2, 3)
}
func addNumbers(x, y, z int) {
a := x + y
b := x + z
c := y + z
fmt.Println(a, b, c)
}
Cuando creamos la firma de la función addNumbers
, no necesitamos volver a especificar el tipo; solo lo hicimos al final.
Pasamos el número 1
para el parámetro x
, el 2
para el y
y el 3
para el z
. Estos valores corresponden a cada parámetro en el orden en el que se proporcionan.
El programa realiza los siguientes cálculos sobre la base de los valores que pasamos a los parámetros:
a = 1 + 2
b = 1 + 3
c = 2 + 3
La función también imprime a
, b
y c
, y según este cálculo esperamos que a
sea igual a 3
, b
a 4
, y c
a 5
. Ejecutaremos el programa:
- go run add_numbers.go
Output3 4 5
Cuando pasamos 1
, 2
y 3
como parámetros a la función addNumbers()
, recibimos el resultado esperado.
Los parámetros son argumentos que suelen definirse como variables en las definiciones de las funciones. Les puede asignar valores cuando ejecute el método y pasar los argumentos a la función.
Puede pasar un valor de un parámetro a una función y una función también puede producir un valor.
Una función puede producir un valor con la instrucción return
, que producirá el cierre de una función y, de forma opcional, pasará una expresión al autor de la llamada. El tipo de datos que mostrado también debe especificarse.
Hasta ahora, usamos la instrucción fmt.Println()
en lugar de return en nuestras fu
nciones. Crearemos un programa que, en lugar de generar impresiones, mostrará una variable.
En un nuevo archivo de texto llamado double.go
, crearemos un programa que duplicará el parámetro x
y mostrará la variable y
. Realizaremos una invocación para imprimir la variable result
, que se forma ejecutando la función double()
con el valor 3
pasado:
package main
import "fmt"
func main() {
result := double(3)
fmt.Println(result)
}
func double(x int) int {
y := x * 2
return y
}
Podemos ejecutar el programa y ver el resultado:
- go run double.go
Output6
El número entero 6
se muestra como resultado, que es lo esperado al multiplicar 3
por 2
.
Si una función especifica una devolución, debe mostrarla como parte del código. Si no lo hace, verá un error de compilación.
Podemos demostrar esto excluyendo la línea con la instrucción return:
package main
import "fmt"
func main() {
result := double(3)
fmt.Println(result)
}
func double(x int) int {
y := x * 2
// return y
}
Ahora, ejecutaremos el programa de nuevo:
- go run double.go
Output./double.go:13:1: missing return at end of function
Sin usar la instrucción return
aquí, el programa no puede realizar la compilación.
Las funciones se cerrarán de inmediato cuando hallen una instrucción return
, aun cuando no se encuentre al final de la función:
package main
import "fmt"
func main() {
loopFive()
}
func loopFive() {
for i := 0; i < 25; i++ {
fmt.Print(i)
if i == 5 {
// Stop function at i == 5
return
}
}
fmt.Println("This line will not execute.")
}
Aquí, iteramos un bucle for
, e indicamos a este que ejecute 25
iteraciones. Sin embargo, dentro del bucle for
, hay una instrucción condicional if
que comprueba si el valor de i
es igual a 5
. Si lo es, emitiremos una instrucción return
. Debido a que se trata de la función loopFive
, una instrucción return
en cualquier punto de la función la cerrará. Como resultado, nunca llegamos a la última línea de esta función para imprimir la instrucción. This line will not execute.
.
El uso de la instrucción return
dentro del bucle for
finaliza la función, por lo que la línea que se encuentra fuera del bucle no se ejecutará. Si, en su lugar, hubiéramos usado una instrucción break
, solo el bucle se habría cerrado en ese momento y la última línea fmt.Println()
se habría ejecutado.
La instrucción return
cierra una función y puede mostrar un valor si se especifica en la firma de la función.
Se puede especificar más de un valor de devolución para una función. Examinaremos el programa repeat.go
y haremos que muestre dos valores. El primero será el valor repetido y el segundo será un error si el parámetro reps
no es un valor superior a 0
:
package main
import "fmt"
func main() {
val, err := repeat("Sammy", -1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(val)
}
func repeat(word string, reps int) (string, error) {
if reps <= 0 {
return "", fmt.Errorf("invalid value of %d provided for reps. value must be greater than 0.", reps)
}
var value string
for i := 0; i < reps; i++ {
value = value + word
}
return value, nil
}
Lo primero que hace la función repeat
es verificar si el argumento reps
es un valor válido. Cualquier valor que no sea superior a 0
provocará un error. Dado a que pasamos el valor -1
, esta rama del código se ejecutará. Tenga en cuenta que cuando se realiza la devolución desde la función, se deben proporcionar los valores de devolución string
y error
. Debido a que los argumentos proporcionados produjeron un error, pasaremos una cadena en blanco para el primer valor mostrado y el error para el segundo.
En la función main()
, podemos recibir los dos valores de devolución declarando dos variables nuevas: value
y err
. Debido a que podría haber un error en la devolución, verificaremos si recibimos un error antes de continuar con nuestro programa. En este ejemplo, recibimos un error. Imprimiremos el error y aplicaremos return
para la función main()
a fin de cerrar el programa.
Si no se produjo un error, imprimiremos el valor de devolución de la función.
Nota: Se recomienda mostrar solo dos o tres valores. Además, todos los errores se deben mostrar siempre como el último valor de devolución de una función.
Al ejecutar el programa, se obtendrá el siguiente resultado:
Outputinvalid value of -1 provided for reps. value must be greater than 0.
En esta sección, analizamos la manera de usar la instrucción return
para mostrar varios valores de una función.
Las funciones son bloques de código de instrucciones que realizan acciones en un programa, lo cual contribuye a que nuestro código sea reutilizable y modular.
Para obtener más información sobre cómo hacer que su código sea más modular, puede leer nuestra guía sobre Cómo escribir paquetes en Go.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!