Clase 3: Funciones, paquetes y manejo de módulos
Objetivos
- Comprender la sintaxis y la estructura básica de las funciones en Go, así como aprender a declarar, llamar y utilizar funciones.
- Organizar el código en paquetes en Go para crear una estructura lógica y modular.
- Familiarizarse con el proceso de importación y uso de paquetes externos en Go.
Contenido de la clase:
1. Declaración y uso de funciones en Go
Las funciones son bloques de código que se utilizan para realizar una tarea específica.
Proporcionan modularidad y reutilización de código al dividir un programa en partes más pequeñas y manejables.
Las funciones se declaran con func seguido del nombre de la función y paréntesis ( ) seguido de llaves { }
- Declaración de funciones
package main
import "fmt"
func sayHello() {
fmt.Println("Hello World !!!")
}
func main() {
sayHello()
}- Función con parámetros
package main
import "fmt"
func sum(parameter int) int {
result := parameter + 1
return result
}
func main() {
response := myFunction(5)
fmt.Println(response) // 6
}- Retornar múltiples valores
package main
import "fmt"
func calculate(base, height float64) (float64, float64) {
var area = base * height
var perimeter = (base + height) * 2
return area, perimeter
}
func main() {
base := 10.8
height := 5.6
area, perimeter := calculate(base, height)
fmt.Printf("El área es: %.2f \n", area)
fmt.Printf("El perímetro es: %.2f", perimeter)
}- Identificador en blanco
package main
import "fmt"
func calculate(base, height float64) (float64, float64) {
var area = base * height
var perimeter = (base + height) * 2
return area, perimeter
}
func main() {
base := 10.8
height := 5.6
area, _ := calculate(base, height)
fmt.Printf("El área es: %.2f \n", area)
}- Retornar valores con nombre
package main
import "fmt"
func calculate(base, height float64) (area, perimeter float64) {
area = base * height
perimeter = (base + height) * 2
return // return implicito
}
func main() {
base := 10.8
height := 5.6
area, perimeter := calculate(base, height)
fmt.Printf("El área es: %.2f \n", area)
fmt.Printf("El perímetro es: %.2f", perimeter)
}- Función Variádica [N número de argumentos]
package main
import "fmt"
// Función variádica que suma un número variable de enteros [elipsis operator]
func sumar(nums ...int) int {
resultado := 0
for _, num := range nums {
resultado += num
}
return resultado
}
func main() {
// Llamada a la función variádica con diferentes números de argumentos
fmt.Println("Suma:", sumar(1, 2, 3)) // Suma: 6
// También puedes pasar un slice como argumento variádico
numeros := []int{1, 2, 3, 4, 5}
// Utilizamos el operador de elipses `...`
fmt.Println("Suma:", sumar(numeros...)) // Suma: 15
}2. Organización de código en paquetes y manejo de módulos.
Hasta ahora solo hemos visto programas de Go que tienen un solo archivo con una función main y un par de funciones más. En un entorno real, este enfoque de escribir todo el código fuente en un solo archivo no es escalable. Se vuelve imposible reutilizar y mantener el código escrito de esta manera. Aquí es donde los paquetes son útiles.
Los paquetes se utilizan para organizar el código, así conseguir una mejor reutilización y legibilidad. Los paquetes son una colección de archivos de origen de Go que residen en el mismo directorio.
Para utilizar un paquete es necesario importar dicho paquete utilizando la palabra clave import.
En go puedes considerar un paquete como todos los archivos que contenga un directorio y un modulo como una colección de paquetes. Para usar el código de un paquete necesitamos importarlo, sin embargo, en Go no existen las importaciones de módulos relativas. Antes de Go 1.8, para importar paquetes (no había modulos) era necesario usar la ruta absoluta, considerando como base la ruta a la que apuntaba la variable de entorno $GOPATH o. A partir de Go 1.11, la manera más sencilla de trabajar con paquetes es usar go mod.
¿Para que sirve un archivo go.mod?
Un archivo de go.mod define un módulo y nos permite establecer el directorio que usaremos como base para importar los paquetes.
¿Qué contiene un archivo go.mod?
El archivo básico de go.mod es muy corto, dentro de este solo se especifíca el nombre del módulo, el cual usaremos para realizar las importanciones y la versión de go.
Crear un archivo go.mod
- Variables de entorno en GO
$ go env- Activar GO111MODULE
$ go env -w GO111MODULE=on- Empezar a usar Go Mod en nuestro proyecto
$ go mod init <modulename>- Importar desde nuestro archivo main.go
package main
import (
"mimodulo/paquete1"
"mimodulo/paquete2"
)Ejercicio
- Estructura del proyecto

- Archivo go.mod
module go-curso-practico
go 1.20- Archivo main.go
package main
import (
"fmt"
"go-curso-practico/area"
)
func main() {
// Datos del rectángulo
length := 5.0
width := 3.0
// Cálculo del área del rectángulo
rectArea := area.CalculateRectangleArea(length, width)
fmt.Printf("El área del rectángulo es: %.2f\n", rectArea)
// Datos del cuadrado
side := 4.0
// Cálculo del área del cuadrado
squareArea := area.CalculateSquareArea(side)
fmt.Printf("El área del cuadrado es: %.2f\n", squareArea)
}- Archivo area/rectangleArea.go
package area
// Función para calcular el área de un rectángulo
func CalculateRectangleArea(length float64, width float64) float64 {
return length * width
}- Archivo area/squareArea.go
package area
import "math"
// Función para calcular el área de un cuadrado
func CalculateSquareArea(side float64) float64 {
return math.Pow(side, 2)
}Tips
Hay ocasiones en donde querremos importar paquetes y no usarlos. Para esto basta con agregar un guión bajo antes de la importación.
package main
import (
_ "fmt"
)Go también nos permite declarar un alias a la hora de importar un paquete anteponiendo el alias a la ruta de importación.
package main
import alias "ruta/a/paquete"
var result = alias.MyFunction()Go permite acceder al contenido del paquete de manera directa si importamos usando como alias un punto. De esta manera podemos ignorar el nombre del paquete y acceder directamente a los objetos que contiene
package main
import . "ruta/a/paquete"
var result = MyFunction()3. Importación y uso de paquetes externos.
go get
Go tiene un manejador de modulos equivalente a pip y npm, python y javascript, respectivamente, llamado get.
Para obtener modulos remotos ejecutamos el comando go get en consola seguido de la ruta de nuestro paquete; soporta cualquier repositorio, no solo github. Desde la versión de go 1.18, go get no compila el código que descarga, sino que se limita a agregar, actualizar o remover dependencias en el archivo go.mod.
- Librerías de prueba
$ go get github.com/google/uuid- Archivo go.sum
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=- Archivo main.go
package main
import "github.com/google/uuid"
func main() {
uuid := uuid.New()
fmt.Println(uuid)
}go install
Por otro lado, go install no descarga código, sino que compila un modulo e instala el binario en $GOPATH/bin, ignorando el contenido del archivo go.mod cuando se le especifica una versión a través de la linea de comandos.
Go install generalmente se usará para instalar comandos
En resumen, go get se utiliza para descargar y gestionar dependencias de un proyecto, mientras que go installse utiliza para compilar, generar y almacenar programas principales o ejecutables en el GOPATH o en el módulo Go actual. Ambos comandos son útiles para gestionar proyectos y dependencias en Go.
Recursos GO
- Go Awesome:
Go Awesomees un repositorio de GitHub que contiene una lista curada de bibliotecas y recursos populares en el ecosistema de Go. Proporciona una estructura organizada de categorías, lo que facilita la navegación y la búsqueda de bibliotecas específicas. Las listas de Go Awesome son mantenidas por la comunidad y se pueden contribuir a través de solicitudes de extracción en GitHub. Sin embargo, no proporciona información detallada sobre cada biblioteca y generalmente redirige a otros sitios, como repositorios de GitHub o sitios web oficiales, para obtener más detalles y documentación.
- pkg.go.dev:
pkg.go.deves un sitio web oficial de Go mantenido por el equipo de Go de Google. Proporciona una interfaz de búsqueda y exploración de bibliotecas y paquetes en el ecosistema de Go. A diferencia de Go Awesome,pkg.go.devmuestra información más detallada para cada biblioteca, incluyendo documentación, ejemplos de uso, estadísticas de descargas y versiones, entre otros detalles. También cuenta con una interfaz de búsqueda más avanzada y permite filtrar y ordenar resultados en función de diferentes criterios.
4. Tarea
- Escribe un programa en Go que calcule el área de un círculo. El programa debe solicitar al usuario que ingrese el radio del círculo y luego mostrar el área calculada en la salida.
// Solución
package main
import (
"fmt"
"math"
)
func calculateCircleArea(radius float64) float64 {
return math.Pi * math.Pow(radius, 2)
}
func main() {
var radius float64
fmt.Print("Ingrese el radio del círculo: ")
fmt.Scanln(&radius)
area := calculateCircleArea(radius)
fmt.Printf("El área del círculo con radio %.2f es: %.2f\n", radius, area)
}- Implementa una función en Go que calcule el factorial de un número dado. Luego llama a esa función desde la función main y muestra el resultado en pantalla.
// Solución
package main
import "fmt"
// Función para calcular el factorial de un número
func factorial(n int) int {
if n == 0 {
return 1
}
return n * factorial(n-1)
}
func main() {
var num int
fmt.Print("Ingresa un número: ")
fmt.Scanln(&num)
result := factorial(num)
fmt.Printf("El factorial de %d es %d\n", num, result)
}5. Recursos
- Funciones y paquetes: https://coffeebytes.dev/go-funciones-argumentos-y-el-paquete-fmt/
- Uso de funciones: https://apuntes.de/golang/uso-de-funciones/
- Funciones que regresan múltiples valores: https://apuntes.de/golang/funciones-que-regresan-multiples-valores/
- Funciones Variádicas: https://apuntes.de/golang/funciones-variadicas/
- Uso de paquetes de terceros: https://apuntes.de/golang/uso-de-paquetes-de-terceros/
- Creación y uso de paquetes: https://apuntes.de/golang/paquetes/
